diff --git a/toGPA_G1_G6_MinMaxVectorPlots/AustinG1G6.m b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/AustinG1G6.m
similarity index 94%
rename from toGPA_G1_G6_MinMaxVectorPlots/AustinG1G6.m
rename to Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/AustinG1G6.m
index 9cd69db..0e50dea 100644
--- a/toGPA_G1_G6_MinMaxVectorPlots/AustinG1G6.m
+++ b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/AustinG1G6.m
@@ -1,41 +1,53 @@
-clc
-clear all
-
-currentFolder = pwd;
-folderPath = horzcat(currentFolder,'\Input')
-D = genpath(folderPath);
-fileFolders = split(D,';');
-max = size(fileFolders);
-max = max(1,1);
-i = 0;
-for i = 2:max
- fileFolders{i,1};
- currentfile = string(fileFolders{i,1});
- S = strcat(currentfile,'\','*.DAT');
-
- files = dir(S);
- for file = files'
- the_size = file.bytes;
- if the_size > 10000
- dat_file = strcat(currentfile,'\',file.name);
- dat_file = char(dat_file);
- cfg_file = strcat(dat_file(1:end-3),'CFG');
- waveFormCfg = readCFG_COMTRADE(cfg_file);
- waveFormDat = readDAT_COMTRADE(dat_file,waveFormCfg);
- [Imat,Vmat,~,~] = groupVoltCurr(waveFormDat.analog);
- group6PlotV3(waveFormCfg,Vmat,Imat,dat_file,currentFolder,i);
- i = i + 1
- end
+function tags = group6PlotV3Analytic(Voltage, Current, Fs, Setting)
+ tags = [];
+ if ~Setting.ExecuteAnalytic
+ return
end
-end
-
-
-
-
+ Vmat = [];
+ Imat = [];
+ Vmat = cat(1, Vmat, Voltage(:,1)'); % VX1
+ Vmat = cat(1, Vmat, Voltage(:,2)'); % VX2
+ Vmat = cat(1, Vmat, Voltage(:,3)'); % VX3
+ Vmat = cat(1, Vmat, Voltage(:,4)'); % VY1
+ Vmat = cat(1, Vmat, Voltage(:,5)'); % VY2
+ Vmat = cat(1, Vmat, Voltage(:,6)'); % VY3
+ Imat = cat(1, Imat, Current(:,1)'); % I1
+ Imat = cat(1, Imat, Current(:,2)'); % I2
+ Imat = cat(1, Imat, Current(:,3)'); % I3
+
+ cfg = struct;
+ cfg.station_name = convertStringsToChars(Setting.Station);
+ cfg.recording_device = convertStringsToChars(Setting.Device);
+ cfg.lf = Setting.SystemFrequency;
+ cfg.samp = Fs;
+ cfg.endsamp = Setting.SampleCount;
+ cfg.startdate = convertStringsToChars(Setting.EventDate);
+ cfg.starttime = convertStringsToChars(Setting.EventTime);
+
+ dat_file = convertStringsToChars(Setting.InputFilename);
+ outputFolder = convertStringsToChars(Setting.OutputFolder);
+
+ result = group6PlotV3(cfg, Vmat, Imat, dat_file, outputFolder, 0);
+
+ if isfield(result, 'g1PlotFilePath')
+ tag = struct;
+ tag.Name = 'G1 Vector Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.g1PlotFilePath;
+ tags = [tags, tag];
+ end
+ if isfield(result, 'g6PlotFilePath')
+ tag = struct;
+ tag.Name = 'G6 MinMax Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.g6PlotFilePath;
+ tags = [tags, tag];
+ end
+end
-function group6PlotV3(wfCfg,Vmat,Imat,dat_file,currentFolder,i)
+function sb = group6PlotV3(wfCfg,Vmat,Imat,dat_file,currentFolder,i)
try
@@ -331,6 +343,7 @@ function group6PlotV3(wfCfg,Vmat,Imat,dat_file,currentFolder,i)
warning off MATLAB:print:UIControlsScaled %surpresses resizing warning
set(figMMA,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
print(figMMA,plotFilePath1,'-dpng');
+ sb.g6PlotFilePath = plotFilePath1;
% log NLTimage
dTxt = split(plotFilePath1,"\");
nltIm.DisplayText = dTxt(end);
@@ -518,6 +531,7 @@ function group6PlotV3(wfCfg,Vmat,Imat,dat_file,currentFolder,i)
warning off MATLAB:print:UIControlsScaled
set(figVector,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
print(figVector,plotFilePathVec,'-dpng','-r72');
+ sb.g1PlotFilePath = plotFilePathVec;
dTxt = split(plotFilePathVec,"\");
nltIm.DisplayText = dTxt(end);
nltIm.Group = 1;
diff --git a/toGPA_G1_G6_MinMaxVectorPlots/MIT_license.txt b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/MIT_license.txt
similarity index 100%
rename from toGPA_G1_G6_MinMaxVectorPlots/MIT_license.txt
rename to Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/MIT_license.txt
diff --git a/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/SnC_G1_G6_MinMaxVectorPlots.prj b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/SnC_G1_G6_MinMaxVectorPlots.prj
new file mode 100644
index 0000000..8ea1b20
--- /dev/null
+++ b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/SnC_G1_G6_MinMaxVectorPlots.prj
@@ -0,0 +1,139 @@
+
+
+ SnC_G1_G6_MinMaxVectorPlots
+
+
+ 1.0
+
+
+
+
+
+
+
+ \SnC_G1_G6_MinMaxVectorPlots\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\SnC_G1_G6_MinMaxVectorPlots\for_testing
+ ${PROJECT_ROOT}\SnC_G1_G6_MinMaxVectorPlots\for_redistribution_files_only
+ ${PROJECT_ROOT}\SnC_G1_G6_MinMaxVectorPlots\for_redistribution
+ ${PROJECT_ROOT}\SnC_G1_G6_MinMaxVectorPlots
+ false
+
+ subtarget.net.component
+
+ SnC_G1_G6_MinMaxVectorPlots
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ SnC_G1_G6_MinMaxVectorPlots
+ Analytic
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G1_G6_MinMaxVectorPlots
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\AustinG1G6.m
+
+
+
+
+ ${PROJECT_ROOT}\AustinG1G6.m
+
+
+
+
+
+
+
+
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G1_G6_MinMaxVectorPlots\SnC_G1_G6_MinMaxVectorPlots\for_testing\SnC_G1_G6_MinMaxVectorPlots.dll
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G1_G6_MinMaxVectorPlots\SnC_G1_G6_MinMaxVectorPlots\for_testing\SnC_G1_G6_MinMaxVectorPlots_overview.html
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G1_G6_MinMaxVectorPlots\SnC_G1_G6_MinMaxVectorPlots\for_testing\SnC_G1_G6_MinMaxVectorPlotsNative.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/toGPA_G1_G6_MinMaxVectorPlots/groupVoltCurr.m b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/groupVoltCurr.m
similarity index 100%
rename from toGPA_G1_G6_MinMaxVectorPlots/groupVoltCurr.m
rename to Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/groupVoltCurr.m
diff --git a/toGPA_G1_G6_MinMaxVectorPlots/readCFG_COMTRADE.m b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/readCFG_COMTRADE.m
similarity index 100%
rename from toGPA_G1_G6_MinMaxVectorPlots/readCFG_COMTRADE.m
rename to Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/readCFG_COMTRADE.m
diff --git a/toGPA_G1_G6_MinMaxVectorPlots/readDAT_COMTRADE.m b/Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/readDAT_COMTRADE.m
similarity index 100%
rename from toGPA_G1_G6_MinMaxVectorPlots/readDAT_COMTRADE.m
rename to Intellirupters/toGPA_G1_G6_MinMaxVectorPlots/readDAT_COMTRADE.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/Austin_G2_RideThrough.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/Austin_G2_RideThrough.m
similarity index 90%
rename from toGPA_G2_IEEE 1668 Ridethrough/Austin_G2_RideThrough.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/Austin_G2_RideThrough.m
index e9db1c2..088ef63 100644
--- a/toGPA_G2_IEEE 1668 Ridethrough/Austin_G2_RideThrough.m
+++ b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/Austin_G2_RideThrough.m
@@ -1,37 +1,47 @@
-clc
-clear all
-
-currentFolder = pwd;
-folderPath = horzcat(currentFolder,'\Input')
-D = genpath(folderPath);
-fileFolders = split(D,';');
-max = size(fileFolders);
-max = max(1,1);
-i = 0;
-for i = 2:max
- fileFolders{i,1};
- currentfile = string(fileFolders{i,1});
- S = strcat(currentfile,'\','*.DAT');
-
- files = dir(S);
- for file = files'
- the_size = file.bytes;
- if the_size > 10000
- GBB_local = importGBBlistFile150(horzcat(currentFolder,'\classification.txt'));
- GBB_local = table2struct(GBB_local);
- dat_file = strcat(currentfile,'\',file.name);
- dat_file = char(dat_file);
- cfg_file = strcat(dat_file(1:end-3),'CFG');
- waveFormCfg = readCFG_COMTRADE(cfg_file);
- waveFormDat = readDAT_COMTRADE(dat_file,waveFormCfg);
- [Imat,Vmat,~,~] = groupVoltCurr(waveFormDat.analog);
- ccPlotRideThroughV4(waveFormCfg,Vmat,Imat,GBB_local,dat_file,i,currentFolder)
- i = i + 1
- end
+function tags = ccPlotRideThroughV4Analytic(Voltage, Current, Fs, Setting)
+ tags = [];
+ if ~Setting.ExecuteAnalytic
+ return
end
-end
-
+ Vmat = [];
+ Imat = [];
+ Vmat = cat(1, Vmat, Voltage(:,1)'); % VX1
+ Vmat = cat(1, Vmat, Voltage(:,2)'); % VX2
+ Vmat = cat(1, Vmat, Voltage(:,3)'); % VX3
+ Vmat = cat(1, Vmat, Voltage(:,4)'); % VY1
+ Vmat = cat(1, Vmat, Voltage(:,5)'); % VY2
+ Vmat = cat(1, Vmat, Voltage(:,6)'); % VY3
+ Imat = cat(1, Imat, Current(:,1)'); % I1
+ Imat = cat(1, Imat, Current(:,2)'); % I2
+ Imat = cat(1, Imat, Current(:,3)'); % I3
+
+ classificationsPath = convertStringsToChars(Setting.ClassificationsPath);
+ GBB_local = importGBBlistFile150(classificationsPath);
+ GBB_local = table2struct(GBB_local);
+
+ cfg = struct;
+ cfg.station_name = convertStringsToChars(Setting.Station);
+ cfg.recording_device = convertStringsToChars(Setting.Device);
+ cfg.lf = Setting.SystemFrequency;
+ cfg.samp = Fs;
+ cfg.endsamp = Setting.SampleCount;
+ cfg.startdate = convertStringsToChars(Setting.EventDate);
+ cfg.starttime = convertStringsToChars(Setting.EventTime);
+
+ dat_file = convertStringsToChars(Setting.InputFilename);
+ outputFolder = convertStringsToChars(Setting.OutputFolder);
+
+ result = ccPlotRideThroughV4(cfg, Vmat, Imat, GBB_local, dat_file, 0, outputFolder);
+
+ if isfield(result, 'plotFilePath')
+ tag = struct;
+ tag.Name = 'G2 IEEE 1668 Ridethrough Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.plotFilePath;
+ tags = [tags, tag];
+ end
+end
function sendBack = ccPlotRideThroughV4(wfCfg,Vmat,Imat,gbb,dat_file,i,currentFolder)
@@ -469,6 +479,7 @@ function sendBack = ccPlotRideThroughV4(wfCfg,Vmat,Imat,gbb,dat_file,i,currentFo
warning off MATLAB:print:UIControlsScaled %surpresses resizing warning
set(fig1668,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
print(fig1668, rtPathFile,'-dpng',plotResolution); % for pdf work space
+ sendBack.plotFilePath = rtPathFile;
fclose('all');
close(fig1668);
diff --git a/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/SnC_G2_IEEE_1668_Ridethrough.prj b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/SnC_G2_IEEE_1668_Ridethrough.prj
new file mode 100644
index 0000000..cc18531
--- /dev/null
+++ b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/SnC_G2_IEEE_1668_Ridethrough.prj
@@ -0,0 +1,148 @@
+
+
+ SnC_G2_IEEE_1668_Ridethrough
+
+
+ 1.0
+
+
+
+
+
+
+
+ \SnC_G2_IEEE_1668_Ridethrough\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\SnC_G2_IEEE_1668_Ridethrough\for_testing
+ ${PROJECT_ROOT}\SnC_G2_IEEE_1668_Ridethrough\for_redistribution_files_only
+ ${PROJECT_ROOT}\SnC_G2_IEEE_1668_Ridethrough\for_redistribution
+ ${PROJECT_ROOT}\SnC_G2_IEEE_1668_Ridethrough
+ false
+
+ subtarget.net.component
+
+ SnC_G2_IEEE_1668_Ridethrough
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ SnC_G2_IEEE_1668_Ridethrough
+ Analytic
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G2_IEEE 1668 Ridethrough
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\Austin_G2_RideThrough.m
+
+
+
+
+ ${PROJECT_ROOT}\Austin_G2_RideThrough.m
+
+
+
+
+
+ ${PROJECT_ROOT}\ccClassifyV2.m
+ ${PROJECT_ROOT}\ccCullPoints.m
+ ${PROJECT_ROOT}\ccSampleStartEndDuration.m
+ ${PROJECT_ROOT}\ccStructDefaults.m
+ ${PROJECT_ROOT}\ccVectorDefinitionsV3.m
+ ${PROJECT_ROOT}\ccVectorPQmatrixVI.m
+ ${PROJECT_ROOT}\importGBBlistFile150.m
+ ${PROJECT_ROOT}\plotResizeAxesTight.m
+
+
+
+
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G2_IEEE 1668 Ridethrough\SnC_G2_IEEE_1668_Ridethrough\for_testing\SnC_G2_IEEE_1668_RidethroughNative.dll
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G2_IEEE 1668 Ridethrough\SnC_G2_IEEE_1668_Ridethrough\for_testing\SnC_G2_IEEE_1668_Ridethrough_overview.html
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G2_IEEE 1668 Ridethrough\SnC_G2_IEEE_1668_Ridethrough\for_testing\SnC_G2_IEEE_1668_Ridethrough.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/ccClassifyV2.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccClassifyV2.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/ccClassifyV2.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccClassifyV2.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/ccCullPoints.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccCullPoints.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/ccCullPoints.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccCullPoints.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/ccSampleStartEndDuration.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccSampleStartEndDuration.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/ccSampleStartEndDuration.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccSampleStartEndDuration.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/ccStructDefaults.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccStructDefaults.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/ccStructDefaults.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccStructDefaults.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/ccVectorDefinitionsV3.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccVectorDefinitionsV3.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/ccVectorDefinitionsV3.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccVectorDefinitionsV3.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/ccVectorPQmatrixVI.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccVectorPQmatrixVI.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/ccVectorPQmatrixVI.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/ccVectorPQmatrixVI.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/classification.txt b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/classification.txt
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/classification.txt
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/classification.txt
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/groupVoltCurr.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/groupVoltCurr.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/groupVoltCurr.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/groupVoltCurr.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/importGBBlistFile150.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/importGBBlistFile150.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/importGBBlistFile150.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/importGBBlistFile150.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/plotResizeAxesTight.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/plotResizeAxesTight.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/plotResizeAxesTight.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/plotResizeAxesTight.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/readCFG_COMTRADE.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/readCFG_COMTRADE.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/readCFG_COMTRADE.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/readCFG_COMTRADE.m
diff --git a/toGPA_G2_IEEE 1668 Ridethrough/readDAT_COMTRADE.m b/Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/readDAT_COMTRADE.m
similarity index 100%
rename from toGPA_G2_IEEE 1668 Ridethrough/readDAT_COMTRADE.m
rename to Intellirupters/toGPA_G2_IEEE 1668 Ridethrough/readDAT_COMTRADE.m
diff --git a/toGPA_G3_FuseTCCcurve/AustinG3.m b/Intellirupters/toGPA_G3_FuseTCCcurve/AustinG3.m
similarity index 83%
rename from toGPA_G3_FuseTCCcurve/AustinG3.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/AustinG3.m
index 039d6f1..a51cb9f 100644
--- a/toGPA_G3_FuseTCCcurve/AustinG3.m
+++ b/Intellirupters/toGPA_G3_FuseTCCcurve/AustinG3.m
@@ -1,33 +1,45 @@
-clc
-clear all
-
-currentFolder = pwd;
-folderPath = horzcat(currentFolder,'\Input')
-D = genpath(folderPath);
-fileFolders = split(D,';');
-max = size(fileFolders);
-max = max(1,1);
-i = 0;
-for i = 2:max
- fileFolders{i,1};
- currentfile = string(fileFolders{i,1});
- S = strcat(currentfile,'\','*.DAT');
-
- files = dir(S);
- for file = files'
- the_size = file.bytes;
- if the_size > 10000
- GBB_local = importGBBlistFile150(horzcat(currentFolder,'\classification.txt'));
- GBB_local = table2struct(GBB_local);
- dat_file = strcat(currentfile,'\',file.name);
- dat_file = char(dat_file);
- cfg_file = strcat(dat_file(1:end-3),'CFG');
- waveFormCfg = readCFG_COMTRADE(cfg_file);
- waveFormDat = readDAT_COMTRADE(dat_file,waveFormCfg);
- [Imat,Vmat,~,~] = groupVoltCurr(waveFormDat.analog);
- ccPlotFuseTCC(waveFormCfg,waveFormDat,Vmat,Imat,GBB_local,currentFolder,dat_file,i)
- i = i + 1
- end
+function tags = ccPlotFuseTCCAnalytic(Voltage, Current, Fs, Setting)
+ tags = [];
+ if ~Setting.ExecuteAnalytic
+ return
+ end
+
+ Vmat = [];
+ Imat = [];
+ Vmat = cat(1, Vmat, Voltage(:,1)'); % VX1
+ Vmat = cat(1, Vmat, Voltage(:,2)'); % VX2
+ Vmat = cat(1, Vmat, Voltage(:,3)'); % VX3
+ Vmat = cat(1, Vmat, Voltage(:,4)'); % VY1
+ Vmat = cat(1, Vmat, Voltage(:,5)'); % VY2
+ Vmat = cat(1, Vmat, Voltage(:,6)'); % VY3
+ Imat = cat(1, Imat, Current(:,1)'); % I1
+ Imat = cat(1, Imat, Current(:,2)'); % I2
+ Imat = cat(1, Imat, Current(:,3)'); % I3
+
+ classificationsPath = convertStringsToChars(Setting.ClassificationsPath);
+ GBB_local = importGBBlistFile150(classificationsPath);
+ GBB_local = table2struct(GBB_local);
+
+ cfg = struct;
+ cfg.station_name = convertStringsToChars(Setting.Station);
+ cfg.recording_device = convertStringsToChars(Setting.Device);
+ cfg.lf = Setting.SystemFrequency;
+ cfg.samp = Fs;
+ cfg.endsamp = Setting.SampleCount;
+ cfg.startdate = convertStringsToChars(Setting.EventDate);
+ cfg.starttime = convertStringsToChars(Setting.EventTime);
+
+ dat_file = convertStringsToChars(Setting.InputFilename);
+ outputFolder = convertStringsToChars(Setting.OutputFolder);
+
+ result = ccPlotFuseTCC(cfg, [], Vmat, Imat, GBB_local, outputFolder, dat_file, 0);
+
+ if isfield(result, 'plotFilePath')
+ tag = struct;
+ tag.Name = 'G3 Suspected Blown Fuse Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.plotFilePath;
+ tags = [tags, tag];
end
end
@@ -253,6 +265,7 @@ function sendBack = ccPlotFuseTCC(dataCFG,dataDAT,Vmatrix,Imatrix,GBB_local,curr
warning off MATLAB:print:UIControlsScaled %surpresses resizing warning
set(figFuse,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
print(figFuse, plotPathFile,'-dpng'); %rwh
+ sendBack.plotFilePath = plotPathFile;
dTxt = split(plotPathFile,"\");
nltIm.DisplayText = dTxt(end);
nltIm.Group = 3;
diff --git a/toGPA_G3_FuseTCCcurve/NBmodel.mat b/Intellirupters/toGPA_G3_FuseTCCcurve/NBmodel.mat
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/NBmodel.mat
rename to Intellirupters/toGPA_G3_FuseTCCcurve/NBmodel.mat
diff --git a/toGPA_G3_FuseTCCcurve/NaiveBayesCl_v2.m b/Intellirupters/toGPA_G3_FuseTCCcurve/NaiveBayesCl_v2.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/NaiveBayesCl_v2.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/NaiveBayesCl_v2.m
diff --git a/Intellirupters/toGPA_G3_FuseTCCcurve/SnC_G3_FuseTCCcurve.prj b/Intellirupters/toGPA_G3_FuseTCCcurve/SnC_G3_FuseTCCcurve.prj
new file mode 100644
index 0000000..95b9513
--- /dev/null
+++ b/Intellirupters/toGPA_G3_FuseTCCcurve/SnC_G3_FuseTCCcurve.prj
@@ -0,0 +1,150 @@
+
+
+ SnC_G3_FuseTCCcurve
+
+
+ 1.0
+
+
+
+
+
+
+
+ \SnC_G3_FuseTCCcurve\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\SnC_G3_FuseTCCcurve\for_testing
+ ${PROJECT_ROOT}\SnC_G3_FuseTCCcurve\for_redistribution_files_only
+ ${PROJECT_ROOT}\SnC_G3_FuseTCCcurve\for_redistribution
+ ${PROJECT_ROOT}\SnC_G3_FuseTCCcurve
+ false
+
+ subtarget.net.component
+
+ SnC_G3_FuseTCCcurve
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ SnC_G3_FuseTCCcurve
+ Analytic
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G3_FuseTCCcurve
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\AustinG3.m
+
+
+
+
+ ${PROJECT_ROOT}\AustinG3.m
+
+
+
+
+
+ ${PROJECT_ROOT}\ccClassifyV2.m
+ ${PROJECT_ROOT}\ccGetTCC.m
+ ${PROJECT_ROOT}\ccPlotFileNameFormatV2.m
+ ${PROJECT_ROOT}\endSampleHilbert.m
+ ${PROJECT_ROOT}\getFuseSize.m
+ ${PROJECT_ROOT}\getNumEvents.m
+ ${PROJECT_ROOT}\importGBBlistFile150.m
+ ${PROJECT_ROOT}\NaiveBayesCl_v2.m
+ ${PROJECT_ROOT}\NBmodel.mat
+ ${PROJECT_ROOT}\plotResizeAxesTight.m
+
+
+
+
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G3_FuseTCCcurve\SnC_G3_FuseTCCcurve\for_testing\SnC_G3_FuseTCCcurveNative.dll
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G3_FuseTCCcurve\SnC_G3_FuseTCCcurve\for_testing\SnC_G3_FuseTCCcurve_overview.html
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G3_FuseTCCcurve\SnC_G3_FuseTCCcurve\for_testing\SnC_G3_FuseTCCcurve.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/toGPA_G3_FuseTCCcurve/ccClassifyV2.m b/Intellirupters/toGPA_G3_FuseTCCcurve/ccClassifyV2.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/ccClassifyV2.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/ccClassifyV2.m
diff --git a/toGPA_G3_FuseTCCcurve/ccGetTCC.m b/Intellirupters/toGPA_G3_FuseTCCcurve/ccGetTCC.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/ccGetTCC.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/ccGetTCC.m
diff --git a/toGPA_G3_FuseTCCcurve/ccLogTextBox.m b/Intellirupters/toGPA_G3_FuseTCCcurve/ccLogTextBox.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/ccLogTextBox.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/ccLogTextBox.m
diff --git a/toGPA_G3_FuseTCCcurve/ccPlotFileNameFormatV2.m b/Intellirupters/toGPA_G3_FuseTCCcurve/ccPlotFileNameFormatV2.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/ccPlotFileNameFormatV2.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/ccPlotFileNameFormatV2.m
diff --git a/toGPA_G3_FuseTCCcurve/ccStructDefaults.m b/Intellirupters/toGPA_G3_FuseTCCcurve/ccStructDefaults.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/ccStructDefaults.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/ccStructDefaults.m
diff --git a/toGPA_G3_FuseTCCcurve/classification.txt b/Intellirupters/toGPA_G3_FuseTCCcurve/classification.txt
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/classification.txt
rename to Intellirupters/toGPA_G3_FuseTCCcurve/classification.txt
diff --git a/toGPA_G3_FuseTCCcurve/endSampleHilbert.m b/Intellirupters/toGPA_G3_FuseTCCcurve/endSampleHilbert.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/endSampleHilbert.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/endSampleHilbert.m
diff --git a/toGPA_G3_FuseTCCcurve/getFuseSize.m b/Intellirupters/toGPA_G3_FuseTCCcurve/getFuseSize.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/getFuseSize.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/getFuseSize.m
diff --git a/toGPA_G3_FuseTCCcurve/getNumEvents.m b/Intellirupters/toGPA_G3_FuseTCCcurve/getNumEvents.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/getNumEvents.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/getNumEvents.m
diff --git a/toGPA_G3_FuseTCCcurve/groupVoltCurr.m b/Intellirupters/toGPA_G3_FuseTCCcurve/groupVoltCurr.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/groupVoltCurr.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/groupVoltCurr.m
diff --git a/toGPA_G3_FuseTCCcurve/importGBBlistFile150.m b/Intellirupters/toGPA_G3_FuseTCCcurve/importGBBlistFile150.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/importGBBlistFile150.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/importGBBlistFile150.m
diff --git a/toGPA_G3_FuseTCCcurve/plotResizeAxesTight.m b/Intellirupters/toGPA_G3_FuseTCCcurve/plotResizeAxesTight.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/plotResizeAxesTight.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/plotResizeAxesTight.m
diff --git a/toGPA_G3_FuseTCCcurve/readCFG_COMTRADE.m b/Intellirupters/toGPA_G3_FuseTCCcurve/readCFG_COMTRADE.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/readCFG_COMTRADE.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/readCFG_COMTRADE.m
diff --git a/toGPA_G3_FuseTCCcurve/readDAT_COMTRADE.m b/Intellirupters/toGPA_G3_FuseTCCcurve/readDAT_COMTRADE.m
similarity index 100%
rename from toGPA_G3_FuseTCCcurve/readDAT_COMTRADE.m
rename to Intellirupters/toGPA_G3_FuseTCCcurve/readDAT_COMTRADE.m
diff --git a/toGPA_G5_Harmonics/AFC.csv b/Intellirupters/toGPA_G5_Harmonics/AFC.csv
similarity index 100%
rename from toGPA_G5_Harmonics/AFC.csv
rename to Intellirupters/toGPA_G5_Harmonics/AFC.csv
diff --git a/toGPA_G5_Harmonics/AustinG5_Harmonics.m b/Intellirupters/toGPA_G5_Harmonics/AustinG5_Harmonics.m
similarity index 96%
rename from toGPA_G5_Harmonics/AustinG5_Harmonics.m
rename to Intellirupters/toGPA_G5_Harmonics/AustinG5_Harmonics.m
index 868f582..01015ed 100644
--- a/toGPA_G5_Harmonics/AustinG5_Harmonics.m
+++ b/Intellirupters/toGPA_G5_Harmonics/AustinG5_Harmonics.m
@@ -1,35 +1,48 @@
-clc
-clear all
-currentFolder = pwd;
-D = genpath('D:\ToGPA\toGPA_G5_Harmonics\Input');
-fileFolders = split(D,';');
-max = size(fileFolders);
-max = max(1,1);
-i = 0;
-for i = 2:max
- fileFolders{i,1};
- currentfile = string(fileFolders{i,1});
- S = strcat(currentfile,'\','*.DAT');
-
- files = dir(S);
- for file = files'
- the_size = file.bytes;
- if the_size > 10000
- GBB_local = importGBBlistFile150SubFunction('D:\ToGPA\toGPA_G5_Harmonics\classification.txt');
- GBB_local = table2struct(GBB_local);
- dat_file = strcat(currentfile,'\',file.name);
- dat_file = char(dat_file);
- cfg_file = strcat(dat_file(1:end-3),'CFG');
- waveFormCfg = readCFG_COMTRADE(cfg_file);
- waveFormDat = readDAT_COMTRADE(dat_file,waveFormCfg);
- [Imat,Vmat,~,~] = groupVoltCurr(waveFormDat.analog);
- group5Harmonics(waveFormCfg,Vmat,Imat,GBB_local,dat_file,i,currentFolder)
- i = i + 1;
- end
+function tags = group5HarmonicsAnalytic(Voltage, Current, Fs, Setting)
+ tags = [];
+ if ~Setting.ExecuteAnalytic
+ return
+ end
+
+ Vmat = [];
+ Imat = [];
+ Vmat = cat(1, Vmat, Voltage(:,1)'); % VX1
+ Vmat = cat(1, Vmat, Voltage(:,2)'); % VX2
+ Vmat = cat(1, Vmat, Voltage(:,3)'); % VX3
+ Vmat = cat(1, Vmat, Voltage(:,4)'); % VY1
+ Vmat = cat(1, Vmat, Voltage(:,5)'); % VY2
+ Vmat = cat(1, Vmat, Voltage(:,6)'); % VY3
+ Imat = cat(1, Imat, Current(:,1)'); % I1
+ Imat = cat(1, Imat, Current(:,2)'); % I2
+ Imat = cat(1, Imat, Current(:,3)'); % I3
+
+ classificationsPath = convertStringsToChars(Setting.ClassificationsPath);
+ GBB_local = importGBBlistFile150SubFunction(classificationsPath);
+ GBB_local = table2struct(GBB_local);
+
+ cfg = struct;
+ cfg.station_name = convertStringsToChars(Setting.Station);
+ cfg.recording_device = convertStringsToChars(Setting.Device);
+ cfg.lf = Setting.SystemFrequency;
+ cfg.samp = Fs;
+ cfg.endsamp = Setting.SampleCount;
+ cfg.startdate = convertStringsToChars(Setting.EventDate);
+ cfg.starttime = convertStringsToChars(Setting.EventTime);
+
+ dat_file = convertStringsToChars(Setting.InputFilename);
+ outputFolder = convertStringsToChars(Setting.OutputFolder);
+
+ result = group5Harmonics(cfg, Vmat, Imat, GBB_local, dat_file, 0, outputFolder);
+
+ if isfield(result, 'plotFilePath')
+ tag = struct;
+ tag.Name = 'G5 Harmonics Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.plotFilePath;
+ tags = [tags, tag];
end
end
-
function sendBack = group5Harmonics(wfCfg,Vmat,Imat,GBBv2s,dat_file,i,currentFolder)
try
Circuit_Phase_Orientation = split(wfCfg.station_name,'.')
@@ -646,15 +659,15 @@ function sendBack = group5Harmonics(wfCfg,Vmat,Imat,GBBv2s,dat_file,i,currentFol
replaceGBBID = strcat(replaceGBBID,',',char(checkGBBID508.gbbID));
allGBBID = [allGBBID string(checkGBBID508.gbbID)];
end
- if ~isempty(replaceGBBID)
- gbbID = replaceGBBID(2:end);
- else
- setTo = 'yes'; %?
- setOther = '---';
- GBBv2s = ccClassifyV2SubFunction(GBBv2s,gbbID,'group5',setTo,setOther,'updateOne');
+ % if ~isempty(replaceGBBID)
+ % gbbID = replaceGBBID(2:end);
+ % else
+ % setTo = 'yes'; %?
+ % setOther = '---';
+ % GBBv2s = ccClassifyV2SubFunction(GBBv2s,gbbID,'group5',setTo,setOther,'updateOne');
- allGBBID = string(gbbID);
- end
+ % allGBBID = string(gbbID);
+ % end
@@ -1162,11 +1175,12 @@ function sendBack = group5Harmonics(wfCfg,Vmat,Imat,GBBv2s,dat_file,i,currentFol
warning off MATLAB:print:UIControlsScaled %surpresses resizing warning
set(figG5,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
- currentFolder = pwd;
+ %currentFolder = pwd;
plotPathFile = [currentFolder,'\Output\',plotFileName1];
print(figG5, plotPathFile,'-dpng') %errors here
+ sendBack.plotFilePath = plotPathFile;
for i = 1:length(allGBBID)
GBBv2s = ccClassifyV2SubFunction(GBBv2s,allGBBID(i),'ignore','ignore',plotPathFile,'savePlotName');
diff --git a/Intellirupters/toGPA_G5_Harmonics/SnC_G5_Harmonics.prj b/Intellirupters/toGPA_G5_Harmonics/SnC_G5_Harmonics.prj
new file mode 100644
index 0000000..c21c288
--- /dev/null
+++ b/Intellirupters/toGPA_G5_Harmonics/SnC_G5_Harmonics.prj
@@ -0,0 +1,148 @@
+
+
+ SnC_G5_Harmonics
+
+
+ 1.0
+
+
+
+
+
+
+
+ \SnC_G5_Harmonics\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\SnC_G5_Harmonics\for_testing
+ ${PROJECT_ROOT}\SnC_G5_Harmonics\for_redistribution_files_only
+ ${PROJECT_ROOT}\SnC_G5_Harmonics\for_redistribution
+ ${PROJECT_ROOT}\SnC_G5_Harmonics
+ false
+
+ subtarget.net.component
+
+ SnC_G5_Harmonics
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ SnC_G5_Harmonics
+ Analytic
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G5_Harmonics
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\AustinG5_Harmonics.m
+
+
+
+
+ ${PROJECT_ROOT}\AustinG5_Harmonics.m
+
+
+
+
+
+ ${PROJECT_ROOT}\AFC.csv
+ ${PROJECT_ROOT}\ccVectorDefinitions.m
+ ${PROJECT_ROOT}\ccVectorDefinitionsV3.m
+ ${PROJECT_ROOT}\ccVectorPQmatrixVI.m
+ ${PROJECT_ROOT}\harmonicCheck_v5.m
+ ${PROJECT_ROOT}\plotResizeAxesTight.m
+ ${PROJECT_ROOT}\searchFor503.m
+ ${PROJECT_ROOT}\searchFor507or508.m
+
+
+
+
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G5_Harmonics\SnC_G5_Harmonics\for_testing\SnC_G5_Harmonics_overview.html
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G5_Harmonics\SnC_G5_Harmonics\for_testing\SnC_G5_HarmonicsNative.dll
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G5_Harmonics\SnC_G5_Harmonics\for_testing\SnC_G5_Harmonics.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/toGPA_G5_Harmonics/ccVectorDefinitions.m b/Intellirupters/toGPA_G5_Harmonics/ccVectorDefinitions.m
similarity index 100%
rename from toGPA_G5_Harmonics/ccVectorDefinitions.m
rename to Intellirupters/toGPA_G5_Harmonics/ccVectorDefinitions.m
diff --git a/toGPA_G5_Harmonics/ccVectorDefinitionsV3.m b/Intellirupters/toGPA_G5_Harmonics/ccVectorDefinitionsV3.m
similarity index 100%
rename from toGPA_G5_Harmonics/ccVectorDefinitionsV3.m
rename to Intellirupters/toGPA_G5_Harmonics/ccVectorDefinitionsV3.m
diff --git a/toGPA_G5_Harmonics/ccVectorPQmatrixVI.m b/Intellirupters/toGPA_G5_Harmonics/ccVectorPQmatrixVI.m
similarity index 100%
rename from toGPA_G5_Harmonics/ccVectorPQmatrixVI.m
rename to Intellirupters/toGPA_G5_Harmonics/ccVectorPQmatrixVI.m
diff --git a/toGPA_G5_Harmonics/classification.txt b/Intellirupters/toGPA_G5_Harmonics/classification.txt
similarity index 100%
rename from toGPA_G5_Harmonics/classification.txt
rename to Intellirupters/toGPA_G5_Harmonics/classification.txt
diff --git a/toGPA_G5_Harmonics/groupVoltCurr.m b/Intellirupters/toGPA_G5_Harmonics/groupVoltCurr.m
similarity index 100%
rename from toGPA_G5_Harmonics/groupVoltCurr.m
rename to Intellirupters/toGPA_G5_Harmonics/groupVoltCurr.m
diff --git a/toGPA_G5_Harmonics/harmonicCheck_v5.m b/Intellirupters/toGPA_G5_Harmonics/harmonicCheck_v5.m
similarity index 100%
rename from toGPA_G5_Harmonics/harmonicCheck_v5.m
rename to Intellirupters/toGPA_G5_Harmonics/harmonicCheck_v5.m
diff --git a/toGPA_G5_Harmonics/plotResizeAxesTight.m b/Intellirupters/toGPA_G5_Harmonics/plotResizeAxesTight.m
similarity index 100%
rename from toGPA_G5_Harmonics/plotResizeAxesTight.m
rename to Intellirupters/toGPA_G5_Harmonics/plotResizeAxesTight.m
diff --git a/toGPA_G5_Harmonics/readCFG_COMTRADE.m b/Intellirupters/toGPA_G5_Harmonics/readCFG_COMTRADE.m
similarity index 100%
rename from toGPA_G5_Harmonics/readCFG_COMTRADE.m
rename to Intellirupters/toGPA_G5_Harmonics/readCFG_COMTRADE.m
diff --git a/toGPA_G5_Harmonics/readDAT_COMTRADE.m b/Intellirupters/toGPA_G5_Harmonics/readDAT_COMTRADE.m
similarity index 100%
rename from toGPA_G5_Harmonics/readDAT_COMTRADE.m
rename to Intellirupters/toGPA_G5_Harmonics/readDAT_COMTRADE.m
diff --git a/toGPA_G5_Harmonics/searchFor503.m b/Intellirupters/toGPA_G5_Harmonics/searchFor503.m
similarity index 100%
rename from toGPA_G5_Harmonics/searchFor503.m
rename to Intellirupters/toGPA_G5_Harmonics/searchFor503.m
diff --git a/toGPA_G5_Harmonics/searchFor507or508.m b/Intellirupters/toGPA_G5_Harmonics/searchFor507or508.m
similarity index 100%
rename from toGPA_G5_Harmonics/searchFor507or508.m
rename to Intellirupters/toGPA_G5_Harmonics/searchFor507or508.m
diff --git a/Intellirupters/toGPA_G7_Replay/AustinG7.m b/Intellirupters/toGPA_G7_Replay/AustinG7.m
new file mode 100644
index 0000000..53644e2
--- /dev/null
+++ b/Intellirupters/toGPA_G7_Replay/AustinG7.m
@@ -0,0 +1,2081 @@
+function tags = p1_g6stateChangeHistoryV2Analytic(Voltage, Current, Fs, Setting)
+ tags = [];
+ if ~Setting.ExecuteAnalytic
+ return
+ end
+
+ Vmat = [];
+ Imat = [];
+ Vmat = cat(1, Vmat, Voltage(:,1)'); % VX1
+ Vmat = cat(1, Vmat, Voltage(:,2)'); % VX2
+ Vmat = cat(1, Vmat, Voltage(:,3)'); % VX3
+ Vmat = cat(1, Vmat, Voltage(:,4)'); % VY1
+ Vmat = cat(1, Vmat, Voltage(:,5)'); % VY2
+ Vmat = cat(1, Vmat, Voltage(:,6)'); % VY3
+ Imat = cat(1, Imat, Current(:,1)'); % I1
+ Imat = cat(1, Imat, Current(:,2)'); % I2
+ Imat = cat(1, Imat, Current(:,3)'); % I3
+
+ classificationsPath = convertStringsToChars(Setting.ClassificationsPath);
+ GBB_local = importGBBlistFile150SubFunction(classificationsPath);
+ GBB_local = table2struct(GBB_local);
+
+ cfg = struct;
+ cfg.station_name = convertStringsToChars(Setting.Station);
+ cfg.recording_device = convertStringsToChars(Setting.Device);
+ cfg.lf = Setting.SystemFrequency;
+ cfg.samp = Fs;
+ cfg.endsamp = Setting.SampleCount;
+ cfg.startdate = convertStringsToChars(Setting.EventDate);
+ cfg.starttime = convertStringsToChars(Setting.EventTime);
+ cfg.eventID = Setting.Event_ID;
+ cfg.soeID = Setting.SOE_ID;
+ cfg.soeTime = Setting.SOE_Time;
+ cfg.incidentID = Setting.Incident_ID;
+
+ dat_file = convertStringsToChars(Setting.InputFilename);
+ outputFolder = convertStringsToChars(Setting.OutputFolder);
+
+ global currentFolder
+ currentFolder = outputFolder
+ result = p1_g6stateChangeHistoryV2(cfg, Vmat, Imat, dat_file, 0, outputFolder);
+
+ if isfield(result, 'plotFilePath')
+ tag = struct;
+ tag.Name = 'G7 State Change Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.plotFilePath;
+ tags = [tags, tag];
+ end
+end
+
+function sb = p1_g6stateChangeHistoryV2(wfCfg,Vmatrix,Imatrix,dat_file,i,currentFolder)
+
+ try
+ Circuit_Phase_Orientation = split(wfCfg.station_name,'.')
+ Circuit = Circuit_Phase_Orientation(1,:)
+ Circuit_Alt = split(Circuit(1,1),'-')
+ Phase_Orientation = split(Circuit_Phase_Orientation(2,:),'-');
+ Phase = Phase_Orientation(1,:);
+ Orientation = Phase_Orientation(2,:);
+ catch
+ Circuit_Phase_Orientation = split(wfCfg.station_name,'-')
+ Circuit = Circuit_Phase_Orientation(1,:)
+ Circuit_Alt = split(Circuit(1,1),'-')
+ Phase_Orientation = split(Circuit_Phase_Orientation(2,:),'-');
+ Phase = Phase_Orientation(1,:);
+ Orientation = Circuit_Phase_Orientation(3,:);
+
+ end
+
+
+ Vmatrix = OrientationCheck(Vmatrix, Orientation); %if YX, rearrange Vmatrix
+
+ newTime = split(dat_file,'.');
+ newTime = char(newTime(2,:));
+ if strlength(Circuit_Phase_Orientation(1,1)) < 7
+ plotFileName1 = append(wfCfg.station_name(1:6),'-',wfCfg.recording_device,'_','G7','_',newTime,'_',int2str(i));
+ forPNG = append(wfCfg.station_name(1:6),'-',wfCfg.recording_device);
+ else
+ plotFileName1 = append(wfCfg.station_name(1:6),'-',wfCfg.recording_device,wfCfg.station_name(7:13),'_','G7','_',newTime,'_',int2str(i));
+ forPNG = append(wfCfg.station_name(1:6),'-',wfCfg.recording_device,wfCfg.station_name(7:13));
+ end
+
+ sb = struct; % sb abbreviation for sendBack
+ valsIn = struct;
+ refPickup = 700; % To calculate percent of pickup
+ gbbID = 'GBB621';
+ updateBy = 'p1_g6stateChangeHistory';
+ setOther = 'no changes - skip waveform';
+ sb.skipNote = 'none'; % lame way to begin documenting waveforms not processed
+
+ sensorConfig = 'V123-I123-V456';
+ % Note: future development may support these additional configurations
+ %sensorConfigListAllOptions = 'V123-I123-V456-i456-iPgn-iAgn'; % depricate, superceded by sensor.Config
+
+ % initialize here instead of ccStructDefaults
+
+ sb.default = 'set';
+ sb.gbbID = gbbID;
+ sb.sensorConfig = sensorConfig;
+ %sb.sensorConfigsSupported = sensorConfigListAllOptions;
+ sb.changeLimit = 5; % forces or limits measured data points
+ sb.linVsMeanDiffLimit = 10; % Alert if change points differ significantly
+ sb.linVsMeanAlert = false; % Alert flag for alarm log (developer review)
+
+ % Waveform cases: only one should be true
+ sb.disturbance = false; % disturbance event detected
+ sb.protection = false; % protection event detected
+ sb.switching = false; % switching operation detected
+ sb.serviceRest = false; % TIE close detected
+ sb.noEvent = false; % no changes detected
+
+ % Sensor cases: (los and noSrc mutually exclusive)
+ % subscript = sensor numbers
+ sb.V123yes = setSensorFlagSubFunction(sensorConfig,'V123'); % configured?
+ sb.V123pq = false; % at least one PQ event detected
+ sb.V123los = false; % had source, then lost at least once
+ sb.V123noSrc = false; % no source during entire waveform
+ sb.v123tktnOffset = 1.35; % center point on normalized plot
+ sb.v123howThick = 0.025; % +/- center point
+ sb.V123fitOffset = 4; % zero offset for mean and linear fit
+ sb.V456yes = setSensorFlagSubFunction(sensorConfig,'V456'); % configured?
+ sb.V456pq = false; % at least one PQ event detected
+ sb.V456los = false; % had source, then lost at least once
+ sb.V456noSrc = false; % no source during entire waveform
+ sb.v456tktnOffset = 1.35; % center point on normalized plot
+ sb.v456howThick = 0.025; % +/- center point
+ sb.V456fitOffset = 0; % zero offset for mean and linear fit
+ sb.I123yes = setSensorFlagSubFunction(sensorConfig,'I123'); % configured?
+ sb.I123fault = false; % fault flag set by logic
+ sb.I123logImag = true; % true = i magnitude, false = log normalized i
+ sb.I123tktnOffset = 1.35; % center point on normalized plot, y axis
+ sb.I123howThick = 0.025; % +/- center point
+ sb.I123fitOffset = 2; % zero offset for mean and linear fit
+ sb.VAyes = false; % Plot changes in power (but nothing logged)
+ % TODO future support
+ sb.iPgnyes = setSensorFlagSubFunction(sensorConfig,'iPgn'); % configured?
+ sb.iPgnfault = false; % pref ground and/or neutral sensor
+ sb.I456yes = setSensorFlagSubFunction(sensorConfig,'I456'); % configured?
+ sb.I456fault = false; % fault detection alternate
+ sb.iAgnyes = setSensorFlagSubFunction(sensorConfig,'iAgn'); % configured?
+ sb.iAgnfault = false; % Alternate ground and/or neutral sensor
+
+ % where is the disturbance relative to me
+ sb.distUp = false; % distrurbance upstream
+ sb.distTrip = false; % disturbance cleared by me (this waveform)
+ sb.distDown = false; % downstream protection event
+
+ % since this is historical, minimum durations filter noise
+ sb.faultMin = 0.25; % cycles (code converts to samples based on sample frequency)
+ sb.pqMin = 3; % cycles (code works in samples)
+
+ % since this is historical, tighter PQ to filter minor PQ events
+ sb.pqMaxPU = 0.75; % allowable sag (PU normalized by peak swell!)
+ sb.pqMinPU = 0.20; % ignore LOS cases
+
+ % Figure parameters
+ sb.figSize = [0 0 1 1];
+ sb.p1space = [0.05 0.66 0.6 0.3]; % plot 1 space
+ sb.p2space = [0.05 0.33 0.6 0.3]; % plot 2 space
+ sb.p3space = [0.05 0 0.6 0.3]; % plot 3 space
+ sb.p4space = [0.65 0.66 0.3 0.3]; % plot 4 space
+ sb.p5space = [0.65 0.33 0.3 0.3]; % plot 5 space
+ sb.fontSz = 0.035; % size of text
+
+ % TODO: compare methods
+ %sb.histLogicVsRudy = false; % true if both approaches detect switching
+ %sb.chgPtsMeanVsLinear = false; % analyze differences between mean and linear
+
+
+
+ % New logic - determine voltage sensor change points
+ vsRef = p1_voltSensorReferenceSubFunction(wfCfg,Vmatrix,Imatrix);
+ if vsRef.changes == 0
+ % Alternative concept is to force a change at midpoint
+
+ return; % Abort processing waveform if no changes
+ end
+ vsRef.chPts = vsRef.chPts'; % transpose so changes and mx are each a single row
+ logMe = strcat(" Changes detected: ",num2str(vsRef.changes));
+ disp(logMe);
+ logMe = strcat(" ---Change points: ",num2str(vsRef.chPts));
+ disp(logMe);
+
+
+ oa = struct;
+ minfaultSamp = round(((wfCfg.samp/60) * 600),0) + 1; % integer > 0
+ minpqSamp = round(((wfCfg.samp/60) * 3),0) + 1; % integer > 0
+ lastN = wfCfg.endsamp;
+
+ plotPathFile = [currentFolder,'\Output\',plotFileName1]
+ inLog = p1_stateChangeDataLogV2SubFunction('getDefaults','dummy','dummy'); % get structures
+ outLog = p1_stateChangeDataLogV2SubFunction('setCommonValues',inLog,'dummy',Circuit,Phase,Orientation,wfCfg); % assigns common values
+ outLog.colValue.PlotFileName = plotPathFile;
+ logMe_cv = outLog.colValue; % local copy of column values strcture
+ logMe_cv.PlotFileName = plotPathFile;
+ logMe_mv1toN = outLog.mv1toN; % local copy of measured values
+ commonStuff = {'nvPH1';'nvPH2';'nvPH3';'mvUnits';'mvNote';'dydtUnits';'cStateNote'; ...
+ 'ElectedCycle';'waveformTimeSlot';'XDAreplayID'};
+ oa.commonStuff = commonStuff; % pass list down to store values
+ oa.comtradeDT = [wfCfg.startdate,',',wfCfg.starttime];
+ oa.samp = wfCfg.samp;
+
+% X_startdate = split(wfCfg.startdate,'/');
+% new_startdate = strcat(string(X_startdate(3,1)),"-", string(X_startdate(2,1)),"-",string(X_startdate(1,1)));
+% new_starttime = datetime(wfCfg.starttime,'format','HH:mm:ss.SSSSSS','TimeZone','America/New_York') - hours(4);
+% if ~isdst(datetime(new_startdate,'TimeZone','America/New_York'))
+% new_starttime = new_starttime - hours(1)
+% end
+
+ X_startdate = split(wfCfg.startdate,'/');
+ new_startdate = strcat(string(X_startdate(3,1)),"-", string(X_startdate(2,1)),"-",string(X_startdate(1,1)));
+ new_startdate = datetime(new_startdate,'format','uuuu-MM-dd HH:mm:ss.SSS','TimeZone','America/New_York')
+ new_starttime = datetime(wfCfg.starttime,'format','HH:mm:ss.SSS','TimeZone','America/New_York')
+ curDateTime = (new_startdate + timeofday(new_starttime)) - hours(4);
+
+ if ~isdst(datetime(curDateTime,'TimeZone','America/New_York'))
+ curDateTime = curDateTime - hours(1)
+ end
+
+ date_time = char(datetime(curDateTime,'format','dd/MM/uuuu HH:mm:ss.SSSSSS'))
+ %date_time = [wfCfg.startdate,' ',char(new_starttime)]
+ %date_time = [wfCfg.startdate,' ',wfCfg.starttime]
+ inTss = ccTimeStampSampleV2SubFunction(date_time,'defaultSOElocal'); % needed to get time info
+ inTss.comtradeDT = oa.comtradeDT; % TODO, unnecessary in V2
+
+
+
+ % Vector analysis, waveforms and rms calculations
+ intoVPQMVI.default = 'getDefaults';
+ intoVPQMVI = ccVectorPQmatrixVISubFunction(intoVPQMVI,wfCfg,Vmatrix,Imatrix);
+ vo = ccVectorPQmatrixVISubFunction(intoVPQMVI,wfCfg,Vmatrix,Imatrix);
+ spc = vo.spc; % samples per cycle
+ oa.spc = spc;
+
+ thr_hz60 = 0.800000000000000;
+ % Determine m1m2 using new voltage reference logic
+ % Step 1, find mxHere and mxHereTime
+ % TODO: add case 0 (no changes) - m1 at waveform center
+ switch vsRef.changes
+ case 0
+ mxHere = round((lastN/2),0);
+ vsRef.mxHere = mxHere;
+ mxHereTime = strings(1,1);
+ inTss.sample = mxHere;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ vsRef.mxHereTime = string(mxTd.CTdateStringEvent);
+
+ case 1
+ % One change produces two measurements
+ % mxHere - x axis point for all sensors
+ xPointM1 = round((vsRef.chPts/2),0);
+ xPointM2 = round(((vsRef.chPts + lastN)/2),0) - 1;
+ mxHere = [xPointM1, xPointM2];
+ vsRef.mxHere = mxHere;
+ mxHereTime = strings(1,2);
+ inTss.sample = xPointM1;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(1) = string(mxTd.CTdateStringEvent);
+ inTss.sample = xPointM2;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(2) = string(mxTd.CTdateStringEvent);
+ vsRef.mxHereTime = mxHereTime;
+
+ case 2
+ % Two changes produces three measurements
+ % mxHere - x axis point for all sensors
+ xPointM1 = round((vsRef.chPts(1)/2),0);
+ xPointM2 = round(((vsRef.chPts(1)+vsRef.chPts(2))/2),0);
+ xPointM3 = round(((vsRef.chPts(2) + lastN)/2),0) - 1;
+ mxHere = [xPointM1, xPointM2, xPointM3];
+ vsRef.mxHere = mxHere;
+ % mxHereTime - corresponding time at these points
+ mxHereTime = strings(1,3);
+ inTss.sample = xPointM1;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(1) = string(mxTd.CTdateStringEvent);
+ inTss.sample = xPointM2;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(2) = string(mxTd.CTdateStringEvent);
+ inTss.sample = xPointM3;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(3) = string(mxTd.CTdateStringEvent);
+ vsRef.mxHereTime = mxHereTime;
+
+ otherwise
+ % original no change found, force m1, m2 rather than crash
+ % Elected points at 25% and 75% of waveform
+ vsRef.chPts = round((lastN/2),0);
+ xPointM1 = round((lastN * 0.25),0);
+ xPointM2 = round((lastN * 0.75),0);
+ mxHere = [xPointM1, xPointM2];
+ vsRef.mxHere = mxHere;
+ % mxHereTime - corresponding time at these points
+ mxHereTime = strings(1,2);
+ inTss.sample = xPointM1;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(1) = string(mxTd.CTdateStringEvent);
+ inTss.sample = xPointM2;
+ mxTd = ccTimeStampSampleV2SubFunction(inTss,'findTimeSOElocal');
+ mxHereTime(2) = string(mxTd.CTdateStringEvent);
+ vsRef.mxHereTime = mxHereTime;
+ end
+ mxPts = length(mxHere);
+
+ % For each sensor, log the RMS value at mxHere points
+ % Step 2, log the data points
+ other = struct; % to pass extra info into p1_stateChangeColorMapV2SubFunction
+ other.V123yes = false; % init
+ other.V456yes = false; % init
+
+ value = vo.vRMS1toEnd(mxHere,1:3);
+ valsIn.mxHere = mxHere;
+ valsIn.mxHereTime = mxHereTime;
+ valsIn.sensor = ["V1","V2","V3"];
+ valsIn.value = round(value,0);
+ valsIn.value(valsIn.value < 0) = 0; % Suppress negative rms values
+ valsIn.valUnits = 'VoltsRMS';
+ V123valsIn = valsIn;
+ other.V123valsIn = V123valsIn;
+ other.sig1 = vsRef.sig1;
+ [mxColorV123, mxColorIDV123] = p1_stateChangeColorMapV2SubFunction('V123',mxHere,vo,other);
+ other.V123yes = true; % required for V456, persist V123
+ other.mxColorV123 = mxColorV123; % persist V123
+ newRecs.useCol = 5; % 4 = gen1 logic, 5 = sanity logic (allows flexibility based on sensor group)
+ newRecs.addRows = mxPts;
+ newRecs.mxHere = mxHere;
+ newRecs.mxColor = mxColorV123;
+ newRecs.mxColorMapInt = mxColorIDV123;
+ newRecs.valsIn = V123valsIn;
+ newRecs.signal = vsRef.sig1(mxHere); % reminder sig1 = V123
+ outLog.colValue.ChannelName = 'V123';
+ [~] = p1_stateChangeDataLogV2SubFunction('addRecord',outLog,newRecs);
+
+
+
+ value = vo.vRMS1toEnd(mxHere,4:6);
+ valsIn.mxHere = mxHere;
+ valsIn.mxHereTime = mxHereTime;
+ valsIn.sensor = ["V4","V5","V6"];
+ valsIn.value = round(value,0);
+ valsIn.value(valsIn.value < 0) = 0; % Suppress negative rms values
+ valsIn.valUnits = 'VoltsRMS';
+ V456valsIn = valsIn;
+ other.V456valsIn = V456valsIn;
+ other.sig2 = vsRef.sig2;
+ [mxColorV456, mxColorIDV456] = p1_stateChangeColorMapV2SubFunction('V456',mxHere,vo,other);
+ other.V456yes = true;
+ other.mxColorV456 = mxColorV456;
+ newRecs.useCol = 5; % 4 = gen1 logic, 5 = sanity logic (allows flexibility based on sensor group)
+ newRecs.addRows = mxPts;
+ newRecs.mxHere = mxHere;
+ newRecs.mxColor = mxColorV456;
+ newRecs.mxColorMapInt = mxColorIDV456;
+ newRecs.valsIn = V456valsIn;
+ newRecs.signal = vsRef.sig2(mxHere); % reminder sig2 = V456
+ outLog.colValue.ChannelName = 'V456';
+ [~] = p1_stateChangeDataLogV2SubFunction('addRecord',outLog,newRecs);
+
+
+ % Note: current will be plotted as % of pickup (700 amps)
+ % Solves the problem of normalizing when not all three phases are faulted
+ % Also, plot all three phases
+
+ value = vo.iRMS1toEnd(mxHere,1:3);
+ valsIn.mxHere = mxHere;
+ valsIn.mxHereTime = mxHereTime;
+ valsIn.sensor = ["I1","I2","I3"];
+ valsIn.value = round(value,0);
+ valsIn.value(valsIn.value < 0) = 0; % Suppress negative rms values
+ pctiSig = (vo.iRMS1toEnd(:,1:3)/refPickup) * 100;
+ valsIn.pctiSig = round(pctiSig,2);
+ valsIn.phaseMax = max(valsIn.value); % checks mx and all 3 phases
+ valsIn.norm600 = (600 / refPickup) * 100; % 600 amp reference line
+ valsIn.norm800 = (800 / refPickup) * 100; % 800 amp reference line
+ valsIn.valUnits = 'AmpsRMS';
+ I123valsIn = valsIn;
+ i123Is60HZ = isIt60HzGen2SubFunction(mxHere,spc,lastN,Imatrix',vo,'I123',thr_hz60);
+ other.i123Is60HZ = i123Is60HZ;
+ other.I123valsIn = I123valsIn;
+ [mxColorI123, mxColorIDI123] = p1_stateChangeColorMapV2SubFunction('I123',mxHere,vo,other);
+ other.I123yes = true;
+ other.mxColorI123 = mxColorI123;
+ newRecs.useCol = 4; % 4 = gen1 logic, 5 = sanity logic (allows flexibility based on sensor group)
+ newRecs.addRows = mxPts;
+ newRecs.mxHere = mxHere;
+ newRecs.mxColor = mxColorI123;
+ newRecs.mxColorMapInt = mxColorIDI123;
+ newRecs.valsIn = I123valsIn;
+ signal = round(pctiSig(mxHere,:),2);
+ newRecs.signal = max(signal,[],2); % single data point representing 3 phases
+ outLog.colValue.ChannelName = 'I123';
+ [~] = p1_stateChangeDataLogV2SubFunction('addRecord',outLog,newRecs);
+
+
+ % Set up figure and text box
+ figG6hist = figure('units','normalized','outerposition',[0 0 1 1],'Visible','off');
+
+
+ % PLOT V123
+ % vsRef works for voltage because voltage is the reference!
+
+ p1 = axes('outerposition',[0.03 0.67 0.96 0.28]);
+ legP1 = plot(vsRef.attempt1sig1); % old signal
+ hold on;
+ legP2 = plot(vsRef.sig1); % signal amended with deviation
+ mx1Time = char(vsRef.mxHereTime(1));
+
+
+% X_startdate = split(wfCfg.startdate,'/');
+% new_startdate = strcat(string(X_startdate(3,1)),"-", string(X_startdate(2,1)),"-",string(X_startdate(1,1)));
+% mx1Time = datetime(mx1Time,'format','HH:mm:ss.SSSSSS','TimeZone','America/New_York');
+% TimeR = char(mx1Time);
+% mx1Time = mx1Time - hours(4);
+% if ~isdst(datetime(new_startdate,'TimeZone','America/New_York'))
+% mx1Time = mx1Time - hours(1)
+% end
+% mx1Time_updated = char(mx1Time);
+
+ %mx1Time_updated = char((datetime(mx1Time, 'Format', 'yyyy-MM-dd HH:mm:ss.SSS')));
+ %mx1Time_updated = char((datetime(mx1Time, 'Format', 'yyyy-MM-dd HH:mm:ss.SSS') - hours(5)));
+
+
+ X_startdate = split(wfCfg.startdate,'/');
+ new_startdate = strcat(string(X_startdate(3,1)),"-", string(X_startdate(2,1)),"-",string(X_startdate(1,1)));
+ new_startdate = datetime(new_startdate,'format','uuuu-MM-dd HH:mm:ss.SSS','TimeZone','America/New_York')
+ mx1Time = datetime(mx1Time,'format','HH:mm:ss.SSS','TimeZone','America/New_York')
+ timeR = (new_startdate + timeofday(mx1Time))
+ mx1Time = (new_startdate + timeofday(mx1Time)) - hours(4);
+
+ if ~isdst(datetime(curDateTime,'TimeZone','America/New_York'))
+ mx1Time = curDateTime - hours(1)
+ end
+
+
+ txt = [forPNG,' Volts (V123) - 3PH - deviation (nominal PU * 3) ', ...
+ ' Time at m1: ',char(timeR)];
+ title(txt);
+ ylimUp = 4.0;
+ ylim([-0.1 ylimUp]);
+ ylabel('Volts Per Unit (PH1 + PH2 + PH3)');
+ xlabel('Waveform sample number');
+ % RMS text set-up
+ stYrms = min(V123valsIn.value,[],2);
+ stYpu = round(vsRef.sig1(V123valsIn.mxHere),2);
+ legSt1 = stem(V123valsIn.mxHere,stYpu,'Marker','d','MarkerFaceColor','k','Color','k','LineStyle',':');
+ txtY = zeros(length(V123valsIn.mxHere),1) + (ylimUp - 0.25);
+ lbls = num2str(stYrms);
+ text(V123valsIn.mxHere,txtY,lbls,'HorizontalAlignment','center');
+
+ txtY = txtY - 0.20;
+ text(V123valsIn.mxHere,txtY,mxColorV123(:,5),'HorizontalAlignment','center');
+
+
+ % Samples text set-up
+ txtYsmp = zeros(length(V123valsIn.mxHere),1) + 0.25;
+ lbl2 = num2str(V123valsIn.mxHere');
+ text(V123valsIn.mxHere,txtYsmp,lbl2,'HorizontalAlignment','center');
+ legSt2 = stem(vsRef.chPts,vsRef.sig1(vsRef.chPts),'Marker','x','LineStyle','-.','Color','m');
+ hold off;
+ p1.Position = plotResizeAxesTightSubFunction(p1);
+
+
+ % Plot I123 - changes detected
+ p2 = axes('outerposition',[0.03 0.35 0.96 0.28]);
+
+ legP1 = plot(I123valsIn.pctiSig); % percent of pickup
+ hold on;
+ pmx = I123valsIn.phaseMax;
+ phaseImaxTxt = ['MAX current PH1: ',num2str(pmx(1)),' PH2: ',num2str(pmx(2)),' PH3: ',num2str(pmx(3)),' Amps'];
+ txt = [' --- Current (I123) normalized 3PH sum ',phaseImaxTxt];
+ title(txt);
+ ylimUp = round(((abs(max(max(I123valsIn.pctiSig)))/100) + 1),0) * 100;
+ if ylimUp < 200
+ ylimUp = 150;
+ end
+ ylim([-10 ylimUp]);
+ ylabel('Current - Percent of TCC pickup ');
+ xlabel('Waveform sample number');
+ ln600 = [I123valsIn.norm600 I123valsIn.norm600];
+ ln800 = [I123valsIn.norm800 I123valsIn.norm800];
+ xEnd = length(I123valsIn.pctiSig);
+ legL1 = line([1 xEnd],ln600,'Color','k','LineStyle','-.');
+ legL2 = line([1 xEnd],ln800,'Color','k','LineStyle','-.');
+ stYrmsPH = max(I123valsIn.value,[],2);
+ stYpct = max(I123valsIn.pctiSig(I123valsIn.mxHere,:),[],2);
+ legSt1 = stem(I123valsIn.mxHere,stYpct,'Marker','d','MarkerFaceColor','k','Color','k','LineStyle','-');
+ %txtY = round((stYpct*1.15),0); % add 15% offset for y position
+ %txtIndex = txtY < 100;
+ %if any(txtIndex)
+ % txtY = txtY + (txtIndex * 100); % mitigates crowding around small currents
+ %end
+ lbls = num2str(stYrmsPH); % current magnitude
+ txtY(:) = ylimUp*0.95;
+ text(I123valsIn.mxHere,txtY,lbls,'HorizontalAlignment','center');
+
+ txtY = txtY*0.95;
+ text(I123valsIn.mxHere,txtY,mxColorI123(:,4),'HorizontalAlignment','center');
+
+ hold off;
+ p2.Position = plotResizeAxesTightSubFunction(p2);
+
+
+ % Plot V456 --- PCRs
+
+ p3 = axes('outerposition',[0.03 0.02 0.96 0.28]);
+ legP1 = plot(vsRef.attempt1sig2); % old signal
+ hold on;
+ legP2 = plot(vsRef.sig2); % signal amended with deviation
+ txt = 'Volts (V456) - 3PH - deviation (nominal PU * 3)';
+ title(txt);
+ ylimUp = 4.0;
+ ylim([-0.1 ylimUp]);
+ ylabel('Volts Per Unit (PH1 + PH2 + PH3)');
+ xlabel('Waveform sample number');
+
+ % RMS text
+ stYrms = min(V456valsIn.value,[],2);
+ stYpu = round(vsRef.sig2(V456valsIn.mxHere),2);
+ legSt1 = stem(V456valsIn.mxHere,stYpu,'Marker','d','MarkerFaceColor','k','Color','k','LineStyle',':');
+ txtY = zeros(length(V456valsIn.mxHere),1) + (ylimUp - 0.25);
+ lbls = num2str(stYrms);
+ text(V456valsIn.mxHere,txtY,lbls,'HorizontalAlignment','center');
+
+ % Colors text set-up
+ %txtY = txtY - 0.2;
+ %text(V456valsIn.mxHere,txtY,mxColorV456(:,4),'HorizontalAlignment','center');
+ txtY = txtY - 0.2;
+ text(V456valsIn.mxHere,txtY,mxColorV456(:,5),'HorizontalAlignment','center');
+
+ % mxHere text
+ txtYsmp = zeros(length(V456valsIn.mxHere),1) + 0.25;
+ lbl2 = num2str(V456valsIn.mxHere');
+ text(V456valsIn.mxHere,txtYsmp,lbl2,'HorizontalAlignment','center');
+ legSt2 = stem(vsRef.chPts,vsRef.sig2(vsRef.chPts),'Marker','x','LineStyle','-.','Color','m');
+ hold off;
+ p3.Position = plotResizeAxesTightSubFunction(p3);
+
+ % save plot
+ warning off MATLAB:print:UIControlsScaled %surpresses resizing warning
+ set(figG6hist,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
+ print(figG6hist, plotPathFile,'-dpng');
+ sb.plotFilePath = plotPathFile;
+ close(figG6hist);
+
+
+
+
+end
+
+function sendBack = ccVectorPQmatrixVISubFunction(intoVPQMVI,wfCfg,Vmat,Imat)
+ sendBack = struct;
+
+ if strcmp(intoVPQMVI.default,'getDefaults')
+ sendBack.default = 'set';
+ sendBack.vecCount = -1;
+ sendBack.options = 'none';
+ sendBack.flagPUoffset = false;
+ sendBack.iSensorInvert = 'notTested'; % check for inverted current sensors
+ sendBack.LOSallThreshold = 0.2; % defined LOS
+ return;
+ end
+
+ [lastN,lastS] = size(Vmat');
+ if lastN == 0
+ sendBack.vecCount = 0;
+ return
+ end
+
+ % common stuff
+ vecIcount = -1;
+ vecVcount = -1;
+ puOffset = -1; % if flagPUoffset is true, calculate ofset of nominal LG voltage
+ sendBack.vsTotal = lastS;
+ volts = Vmat';
+
+
+ % correcting rms first and last cycle
+ rmsWin = 64;
+ vPlus2 = [Vmat(:,1:rmsWin),Vmat,Vmat(:,lastN-rmsWin+1:lastN)];
+ vRmsPlus2 = envelope(vPlus2',rmsWin,'rms');
+ voltsRMS = vRmsPlus2(rmsWin+1:lastN+rmsWin,:);
+ voltsRMSpu = voltsRMS / 7200;
+ sendBack.vRMS1toEnd = voltsRMS;
+ sendBack.voltsRMSpu = voltsRMSpu;
+ % END correction
+
+ % calculate samples per cycle and lastN
+ spc = round((wfCfg.samp / wfCfg.lf),0); % samples per cycle
+ sendBack.spc = spc;
+ sendBack.lastN = wfCfg.endsamp;
+
+ % LOSall test (vector true when all three phases < threshold)
+ losAll = voltsRMSpu < intoVPQMVI.LOSallThreshold;
+ losAllAlert = any(any(losAll),'all');
+ [rx,vSensors] = size(losAll);
+ los123 = zeros(rx,1);
+ los456 = zeros(rx,1);
+ los123Alert = false;
+ los456Alert = false;
+ if losAllAlert && (vSensors == 3)
+ los123 = losAll(:,1) & losAll(:,2) & losAll(:,3);
+ los123Alert = any(los123);
+ end
+ if losAllAlert && (vSensors == 6)
+ los123 = losAll(:,1) & losAll(:,2) & losAll(:,3);
+ los123Alert = any(los123);
+ los456 = losAll(:,4) & losAll(:,5) & losAll(:,6);
+ los456Alert = any(los456);
+ end
+ sendBack.los123Alert = los123Alert;
+ sendBack.los123 = los123;
+ sendBack.los456Alert = los456Alert;
+ sendBack.los456 = los456;
+ sendBack.nominalLG = 7200;
+ sendBack.systemVoltage = '12KV';
+ sendBack.losAll = losAll;
+ % END LOSall
+
+ %% Single phasing test & LOSnnnV2
+ sglPh123(1:rx,1) = false;
+ sglPh456(1:rx,1) = false;
+ los123V2(1:rx,1) = false;
+ los456V2(1:rx,1) = false;
+ if vSensors == 3
+ los123xN = sum(losAll(:,1:3),2);
+ sglPh123 = ((los123xN == 1) | (los123xN == 2));
+ los123V2 = (los123xN == 3);
+ end
+ if vSensors == 6
+ los123xN = sum(losAll(:,1:3),2);
+ sglPh123 = ((los123xN == 1) | (los123xN == 2));
+ los123V2 = (los123xN == 3);
+ los456xN = sum(losAll(:,4:6),2);
+ sglPh456 = ((los456xN == 1) | (los456xN == 2));
+ los456V2 = (los456xN == 3);
+ end
+ sendBack.sglPh123 = sglPh123;
+ sendBack.sglPh456 = sglPh456;
+ sendBack.los123V2 = los123V2;
+ sendBack.los456V2 = los456V2;
+
+ if intoVPQMVI.flagPUoffset
+ disp('ERROR: need to log PUoffset logic is not coded yet!!!');
+ puOffset = 0;
+
+ end
+
+ vGood = ((0.9 <= voltsRMSpu) & (voltsRMSpu < 1.1));
+ sendBack.vGood = vGood;
+ [~,vecVcount] = size(vGood);
+ sendBack.vecVcount = vecVcount;
+
+ % convert binary vGood vector to plot data
+
+ vThinThickGoodUp = zeros(lastN,lastS); % initialize the plot vector
+ vThinThickGoodDown = zeros(lastN,lastS); % initialize the plot vector
+ yOffSet = -2;
+ nextY = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastN - 65;
+ trueCount = sum(vGood(startHere:stopHere,:));
+ for S=1:lastS
+ yOffSet = yOffSet + nextY;
+ if (trueCount(S) < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ vThinThickGoodUp(:,S) = yOffSet + (vGood(:,S) * oneOn);
+ vThinThickGoodDown(:,S) = yOffSet - (vGood(:,S) * oneOn);
+ end
+ if (trueCount(S) >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ vThinThickGoodUp(:,S) = yOffSet + (vGood(:,S) * (oneAll + 0.07)); % attempt to emphasize true
+ vThinThickGoodDown(:,S) = yOffSet + (vGood(:,S) * oneAll);
+ end
+ end
+ thinThickVgood = [vThinThickGoodUp, vThinThickGoodDown];
+ sendBack.thinThickVgood = thinThickVgood;
+
+ % end convert binary vGood vector to plot data
+
+ % vPQ // IEEE vSag OR vSwell // make thinThickfor PQ only
+ vSag = (0.1 <= voltsRMSpu) & (voltsRMSpu < 0.9);
+ sendBack.vSag = vSag;
+
+ vSwell = 1.1 <= voltsRMSpu;
+ sendBack.vSwell = vSwell;
+
+ vPQ = vSag | vSwell;
+ sendBack.vPQ = vPQ;
+
+ % convert binary vPQ vector to plot data
+ vThinThickPQUp = zeros(lastN,lastS); % initialize the plot vector
+ vThinThickPQDown = zeros(lastN,lastS); % initialize the plot vector
+ yOffSet = -2;
+ nextY = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastN - 65;
+ trueCount = sum(vPQ(startHere:stopHere,:));
+ for S=1:lastS
+ yOffSet = yOffSet + nextY;
+ if (trueCount(S) < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ vThinThickPQUp(:,S) = yOffSet + (vPQ(:,S) * oneOn);
+ vThinThickPQDown(:,S) = yOffSet - (vPQ(:,S) * oneOn);
+ end
+ if (trueCount(S) >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ vThinThickPQUp(:,S) = yOffSet + (vPQ(:,S) * (oneAll + 0.07)); % attempt to emphasize true
+ vThinThickPQDown(:,S) = yOffSet + (vPQ(:,S) * oneAll);
+ end
+ end
+ thinThickPQ = [vThinThickPQUp, vThinThickPQDown];
+ sendBack.thinThickPQ = thinThickPQ;
+
+
+ vLOS = voltsRMSpu < 0.1;
+ sendBack.vLOS = vLOS;
+ % convert binary vLOS vector to plot data
+ %
+ vThinThickLOSUp = zeros(lastN,lastS); % initialize the plot vector
+ vThinThickLOSDown = zeros(lastN,lastS); % initialize the plot vector
+ yOffSet = -2;
+ nextY = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastN - 65;
+ trueCount = sum(vLOS(startHere:stopHere,:));
+ for S=1:lastS
+ yOffSet = yOffSet + nextY;
+ if (trueCount(S) < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ vThinThickLOSUp(:,S) = yOffSet + (vLOS(:,S) * oneOn);
+ vThinThickLOSDown(:,S) = yOffSet - (vLOS(:,S) * oneOn);
+ end
+ if (trueCount(S) >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ vThinThickLOSUp(:,S) = yOffSet + (vLOS(:,S) * (oneAll + 0.07)); % attempt to emphasize true
+ vThinThickLOSDown(:,S) = yOffSet + (vLOS(:,S) * oneAll);
+ end
+ end
+ thinThickLOS = [vThinThickLOSUp, vThinThickLOSDown];
+ sendBack.thinThickLOS = thinThickLOS;
+
+
+ [lastNi,lastSi] = size(Imat');
+
+ rmsWin = 64;
+ iPlus2 = [Imat(:,1:rmsWin),Imat,Imat(:,lastNi-rmsWin+1:lastNi)];
+ iRmsPlus2 = envelope(iPlus2',rmsWin,'rms');
+ currentRMS = iRmsPlus2(rmsWin+1:lastNi+rmsWin,:);
+ sendBack.iRMS1toEnd = currentRMS;
+ % end correction
+
+ iGood = ((8 <= currentRMS) & (currentRMS < 800));
+ sendBack.iGood = iGood;
+
+ % convert binary iGood vector to plot data
+ %
+ iThinThickGoodUp = zeros(lastNi,lastSi); % initialize the plot vector
+ iThinThickGoodDown = zeros(lastNi,lastSi); % initialize the plot vector
+ yOffSet = -2;
+ nextY = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(iGood(startHere:stopHere,:));
+ for S=1:lastSi
+ yOffSet = yOffSet + nextY;
+ if (trueCount(S) < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ iThinThickGoodUp(:,S) = yOffSet + (iGood(:,S) * oneOn);
+ iThinThickGoodDown(:,S) = yOffSet - (iGood(:,S) * oneOn);
+ end
+ if (trueCount(S) >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ iThinThickGoodUp(:,S) = yOffSet + (iGood(:,S) * (oneAll + 0.07)); % attempt to emphasize true
+ iThinThickGoodDown(:,S) = yOffSet + (iGood(:,S) * oneAll);
+ end
+ end
+ thinThickIgood = [iThinThickGoodUp, iThinThickGoodDown];
+ sendBack.thinThickIgood = thinThickIgood;
+
+
+ % fault current
+ iFault = (800 <= currentRMS);
+ sendBack.iFault = iFault;
+ sendBack.ibsF = iFault(1,:);
+ sendBack.caeF = iFault(end,:);
+
+ iThinThickUp = zeros(lastNi,lastSi); % initialize the plot vector
+ iThinThickDown = zeros(lastNi,lastSi); % initialize the plot vector
+ yOffSet = -2;
+ nextY = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(iFault(startHere:stopHere,:));
+ for S=1:lastSi
+ yOffSet = yOffSet + nextY;
+ if (trueCount(S) < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ iThinThickUp(:,S) = yOffSet + (iFault(:,S) * oneOn);
+ iThinThickDown(:,S) = yOffSet - (iFault(:,S) * oneOn);
+ end
+ if (trueCount(S) >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ iThinThickUp(:,S) = yOffSet + (iFault(:,S) * (oneAll + 0.07)); % attempt to emphasize true
+ iThinThickDown(:,S) = yOffSet + (iFault(:,S) * oneAll);
+ end
+ end
+ thinThickIfault = [iThinThickUp, iThinThickDown];
+ sendBack.thinThickIfault = thinThickIfault;
+
+ % end iFault
+
+ % no current
+ iNot = (currentRMS < 8);
+ sendBack.iNot = iNot;
+ % convert binary vLOS vector to plot data
+ %
+ iThinThickUp = zeros(lastNi,lastSi); % initialize the plot vector
+ iThinThickDown = zeros(lastNi,lastSi); % initialize the plot vector
+ yOffSet = -2;
+ nextY = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(iNot(startHere:stopHere,:));
+ for S=1:lastSi
+ yOffSet = yOffSet + nextY;
+ if (trueCount(S) < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ iThinThickUp(:,S) = yOffSet + (iNot(:,S) * oneOn);
+ iThinThickDown(:,S) = yOffSet - (iNot(:,S) * oneOn);
+ end
+ if (trueCount(S) >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ iThinThickUp(:,S) = yOffSet + (iNot(:,S) * (oneAll + 0.07)); % attempt to emphasize true
+ iThinThickDown(:,S) = yOffSet + (iNot(:,S) * oneAll);
+ end
+ end
+ thinThickNot = [iThinThickUp, iThinThickDown];
+ sendBack.thinThickNot = thinThickNot;
+
+ [~,sensors] = size(vGood);
+ vGood3PH = sum(vGood,2) == sensors; % all sensors must be good
+ sendBack.vGood3PH = vGood3PH;
+ [firstX3,lastX3] = size(vGood3PH);
+ thinThickUp = zeros(firstX3,lastX3); % initialize the plot vector
+ thinThickDown = zeros(firstX3,lastX3); % initialize the plot vector
+ yOffSet = 4;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(vGood3PH(startHere:stopHere,:));
+ if (trueCount < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ thinThickUp = yOffSet + (vGood3PH * oneOn);
+ thinThickDown = yOffSet - (vGood3PH * oneOn);
+ end
+ if (trueCount >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ thinThickUp = yOffSet + (vGood3PH * (oneAll + 0.07)); % attempt to emphasize true
+ thinThickDown = yOffSet + (vGood3PH * oneAll);
+ end
+ thinThickVolt3PH = [thinThickUp, thinThickDown];
+ vPQ3PH = sum(vPQ,2) > 0; % any single PQ event detected
+ sendBack.vPQ3PH = vPQ3PH;
+ [firstX3,lastX3] = size(vPQ3PH);
+ thinThickUp = zeros(firstX3,lastX3); % initialize the plot vector
+ thinThickDown = zeros(firstX3,lastX3); % initialize the plot vector
+ yOffSet = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(vPQ3PH(startHere:stopHere,:));
+ if (trueCount < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ thinThickUp = yOffSet + (vPQ3PH * oneOn);
+ thinThickDown = yOffSet - (vPQ3PH * oneOn);
+ end
+ if (trueCount >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ thinThickUp = yOffSet + (vPQ3PH * (oneAll + 0.07)); % attempt to emphasize true
+ thinThickDown = yOffSet + (vPQ3PH * oneAll);
+ end
+ thinThickVolt3PH = [thinThickVolt3PH, thinThickUp, thinThickDown];
+
+ vLOS3PH = sum(vLOS,2) > 0; % any single LOS event detected
+ sendBack.vLOS3PH = vLOS3PH;
+ [firstX3,lastX3] = size(vLOS3PH);
+ thinThickUp = zeros(firstX3,lastX3); % initialize the plot vector
+ thinThickDown = zeros(firstX3,lastX3); % initialize the plot vector
+ yOffSet = 0;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(vLOS3PH(startHere:stopHere,:));
+ if (trueCount < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ thinThickUp = yOffSet + (vLOS3PH * oneOn);
+ thinThickDown = yOffSet - (vLOS3PH * oneOn);
+ end
+ if (trueCount >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ thinThickUp = yOffSet + (vLOS3PH * (oneAll + 0.07)); % attempt to emphasize true
+ thinThickDown = yOffSet + (vLOS3PH * oneAll);
+ end
+ thinThickVolt3PH = [thinThickVolt3PH, thinThickUp, thinThickDown];
+ sendBack.thinThickVolt3PH = thinThickVolt3PH;
+
+ [~,sensors] = size(iGood);
+ iGood3PH = sum(iGood,2) == sensors; % all sensors must be good
+ sendBack.iGood3PH = iGood3PH;
+ [firstX3,lastX3] = size(iGood3PH);
+ thinThickUp = zeros(firstX3,lastX3); % initialize the plot vector
+ thinThickDown = zeros(firstX3,lastX3); % initialize the plot vector
+ yOffSet = 4;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(iGood3PH(startHere:stopHere,:));
+ if (trueCount < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ thinThickUp = yOffSet + (iGood3PH * oneOn);
+ thinThickDown = yOffSet - (iGood3PH * oneOn);
+ end
+ if (trueCount >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ thinThickUp = yOffSet + (iGood3PH * (oneAll + 0.07)); % attempt to emphasize true
+ thinThickDown = yOffSet + (iGood3PH * oneAll);
+ end
+ thinThickCurrent3PH = [thinThickUp, thinThickDown];
+
+ iFault3PH = sum(iFault,2) > 0; % any single Fault event detected
+ sendBack.iFault3PH = iFault3PH;
+ [firstX3,lastX3] = size(iFault3PH);
+ thinThickUp = zeros(firstX3,lastX3); % initialize the plot vector
+ thinThickDown = zeros(firstX3,lastX3); % initialize the plot vector
+ yOffSet = 2;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(iFault3PH(startHere:stopHere,:));
+ if (trueCount < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ thinThickUp = yOffSet + (iFault3PH * oneOn);
+ thinThickDown = yOffSet - (iFault3PH * oneOn);
+ end
+ if (trueCount >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ thinThickUp = yOffSet + (iFault3PH * (oneAll + 0.07)); % attempt to emphasize true
+ thinThickDown = yOffSet + (iFault3PH * oneAll);
+ end
+ thinThickCurrent3PH = [thinThickCurrent3PH, thinThickUp, thinThickDown];
+
+ % end FAULT 3 phase
+ % begin iNot (no current) 3 phase
+ iNot3PH = sum(iNot,2) > 0; % any single LOS event detected
+ sendBack.iNot3PH = iNot3PH;
+ [firstX3,lastX3] = size(iNot3PH);
+ thinThickUp = zeros(firstX3,lastX3); % initialize the plot vector
+ thinThickDown = zeros(firstX3,lastX3); % initialize the plot vector
+ yOffSet = 0;
+ oneOn = 0.27;
+ oneAll = 0.7;
+ startHere = 65;
+ stopHere = lastNi - 65;
+ trueCount = sum(iNot3PH(startHere:stopHere,:));
+ if (trueCount < (stopHere - startHere)) % at least one false or all false (thin line if all false)
+ thinThickUp = yOffSet + (iNot3PH * oneOn);
+ thinThickDown = yOffSet - (iNot3PH * oneOn);
+ end
+ if (trueCount >= (stopHere - startHere)) % always true (in display), minimize true offset (raised double true line)
+ thinThickUp = yOffSet + (iNot3PH * (oneAll + 0.07)); % attempt to emphasize true
+ thinThickDown = yOffSet + (iNot3PH * oneAll);
+ end
+ thinThickCurrent3PH = [thinThickCurrent3PH, thinThickUp, thinThickDown];
+ sendBack.thinThickCurrent3PH = thinThickCurrent3PH;
+
+sendBack.vecCount = vecIcount + vecVcount;
+sendBack.vecIcount = vecIcount;
+
+
+end
+
+function sendBack = ccClassifyV2SubFunction(gbbIn,gbbID,functionName,setTo,setOther,action)
+sendBack = struct;
+% TODO add action 'method2' allowing 1 to N updates
+
+gid = [gbbIn.GBBid];
+g = strcmp(gid,gbbID);
+dataRow = gid(g);
+if isempty(dataRow)
+ sendBack = gbbIn; % modify nothing
+ % TODO error log that gbbID not found
+ return;
+end
+
+if sum(g) > 1
+ sendBack = gbbIn; % modify nothing
+ % TODO error more than one record found (unexpected case)
+ return;
+end
+
+if (~isempty(dataRow) && strcmp(action,'updateOne') && (sum(g) == 1))
+ newGbb = gbbIn;
+ classifyThis = gbbIn(g);
+ if ((classifyThis.TestCount > 0) && ~strcmp(classifyThis.TestResult,setTo)) % conflicting test results
+ classifyThis.TestConflict = string(['conflict-',functionName,'-',setTo]);
+ end
+ if classifyThis.TestCount == 0
+ classifyThis.ResultDeterminedByFunction = string(functionName);
+ classifyThis.TestResult = string(setTo);
+ classifyThis.Other = string(setOther);
+ end
+ classifyThis.TestCount = classifyThis.TestCount + 1;
+ newGbb(g) = classifyThis;
+ sendBack = newGbb;
+ return;
+end
+sendBack = gbbIn;
+end
+
+function sendBack = plotResizeAxesTightSubFunction(axesName)
+ outerpos = axesName.OuterPosition;
+ ti = axesName.TightInset;
+ left = outerpos(1) + ti(1);
+ bottom = outerpos(2) + ti(2);
+ test_width = outerpos(3) - ti(1) - ti(3);
+ test_height = outerpos(4) - ti(2) - ti(4);
+ sendBack = [left bottom test_width test_height];
+end
+
+function sFlag = setSensorFlagSubFunction(sensorConfig,sensorName)
+ sFlag = false;
+ flagNames = split(sensorConfig,'-');
+ foundIt = find(contains(flagNames,sensorName));
+ if foundIt
+ sFlag = true;
+ end
+end
+
+function sendBack = ccTimeStampSampleV2SubFunction(ccTSSinTO,action)
+ format longG; % eliminate pesky scientific nonotation most of the time
+ sendBack = struct;
+
+
+
+ % New Option SOE date time format in local time
+ if strcmp(action,'defaultSOElocal')
+ replayDateFormat = 'yyyy-mm-dd HH:MM:SS.FFF'; % move to ccStructDefaults
+ sendBack.dateFormatIn = replayDateFormat; % basic change from original
+ sendBack.dateFormatToLog = replayDateFormat;
+
+ %sendBack.comtradeDT = ccTSSinTO; % test date
+ %sendBack.dateIn = ccTSSinTO; %test date
+
+ %needs formatted from 10/08/2022 15:56:53.885636
+
+ %sendBack.comtradeDT = '2022/10/08 15:56:53.885';
+ AllDateTime = split(ccTSSinTO)
+ Date = AllDateTime(1,1)
+ Time = char(AllDateTime(2,1))
+ Time = Time(1:end-3)
+
+ AllDate = split(Date,'/')
+ DD = char(AllDate(1,1))
+ MM = char(AllDate(2,1))
+ YYYY = char(AllDate(3,1))
+ myDateTime = strcat(YYYY,'-',MM,'-',DD)
+ myDateTime = [myDateTime,' ',Time]
+
+
+ sendBack.dateIn = myDateTime
+
+ sendBack.sample = 333;
+ sendBack.lineFreq = 60;
+ sendBack.samplesPerCycle = 64;
+ return;
+ end
+
+
+ sendBack.goodData = true; %fatal errors need to set this to false
+ sendBack.error1 = 'none'; %see error checking for assignment
+ sendBack.error2 = 'none'; %see error checking for assignment
+ sendBack.error3 = 'none'; %see error checking for assignment
+
+%%
+% TODO: this needs to be passed in so that all date formats can be changed
+% in a common place
+ %comtradeDTformat = 'dd/mm/yyyy,HH:MM:SS.FFF'; % move to ccStructDefaults
+ %replayDateFormat = 'yyyy-mm-dd HH:MM:SS.FFF'; % move to ccStructDefaults
+% end TODO
+ dateFormatIn = ccTSSinTO.dateFormatIn;
+ dateFormatToLog = ccTSSinTO.dateFormatToLog;
+
+ sampleFreq = ccTSSinTO.lineFreq * ccTSSinTO.samplesPerCycle;
+ deltaSec = ccTSSinTO.sample / sampleFreq;
+ maxMsecSampleError = 0.001 * sampleFreq; % samples represented by 1 msec
+
+ %% swap between soe and comtrade
+ if strcmp(action,'findTimeSOElocal')
+ ccTSSinTO.comtradeDT = ccTSSinTO.dateIn;
+ end
+ %% begin date manipulation - COMTRADE date
+
+ CTdateNum0 = datenum(ccTSSinTO.comtradeDT,dateFormatIn);
+
+ sampleTime0 = CTdateNum0 + seconds(0); %convert to duration
+ CTdateString0 = datestr(CTdateNum0,dateFormatToLog); %convert to replay date time
+ % Calculate cycleTime using COMTRADE date time stamp
+ h = sampleTime0;
+ h.Format = 'h';
+ cycH = str2double(datestr(h,'HH'));
+ secSince00 = cycH * 3600; %convert hours to seconds since midnight
+ m = sampleTime0;
+ m.Format = 'm';
+ cycM = str2double(datestr(m,'MM'));
+ secSince00 = secSince00 + (cycM * 60); %add minutes converted to seconds
+ s = sampleTime0;
+ s.Format = 's';
+ cycS = str2double(datestr(s,'SS.FFF'));
+ secSince00 = secSince00 + cycS;
+ cycleTime0 = secSince00 * ccTSSinTO.lineFreq; %cycles since midnight
+
+
+ %% calculate the date time detals at the sample number
+ sampleTimeEvent = CTdateNum0 + seconds(deltaSec);
+ CTdateStringEvent = datestr(sampleTimeEvent,dateFormatToLog);
+
+ % Calculate cycleTime using specified sample data point
+ h = sampleTimeEvent;
+ h.Format = 'h';
+ cycH = str2double(datestr(h,'HH'));
+ secSince00 = cycH * 3600; %convert hours to seconds since midnight
+ m = sampleTimeEvent;
+ m.Format = 'm';
+ cycM = str2double(datestr(m,'MM'));
+ secSince00 = secSince00 + (cycM * 60); %add minutes converted to seconds
+ s = sampleTimeEvent;
+ s.Format = 's';
+ cycS = str2double(datestr(s,'SS.FFF'));
+ secSince00 = secSince00 + cycS;
+ cycleTimeEvent = secSince00 * ccTSSinTO.lineFreq; %cycles since midnight
+ %sendBack.cycleTimeEvent = cycleTimeEvent;
+
+ %% Error check - has the date rolled over
+ % method 1: cycleTimeAtSample < cycleTimeStart
+ % method 2: cycleTimeAtSample > max number of cycles in a day
+ if (cycleTimeEvent < cycleTime0)
+ errorNote = ['Sample cycle time: ',num2str(cycleTimeEvent) ...
+ ' is less than start cycle: ',num2str(cycleTime0)];
+ sendBack.error1 = errorNote;
+ sendBack.goodData = false;
+ end
+ maxNumCycles = (24 * 3600) * ccTSSinTO.lineFreq;
+ if (cycleTimeEvent >= maxNumCycles)
+ errorNote = ['Date roll over detected - Sample cycle time: ',num2str(cycleTimeEvent) ...
+ ' is greater than max cycles in a day: ',num2str(maxNumCycles)];
+ sendBack.error2 = errorNote;
+ sendBack.goodData = false;
+ end
+
+ %% return the new date time (at the sample passed in)
+ sendBack.CTdateNum0 = CTdateNum0;
+ CTdateNumEvent = datenum(CTdateStringEvent);
+ sendBack.CTdateNumEvent = CTdateNumEvent;
+ sendBack.CTdateString0 = CTdateString0;
+ sendBack.CTdateStringEvent = CTdateStringEvent;
+ sampleXDT = split(CTdateStringEvent,' ');
+ sendBack.sampleDate = char(sampleXDT(1)); %TODO error check array size
+ sendBack.sampleTime = char(sampleXDT(2)); %TODO error check array size
+ sendBack.sampleTime0 = sampleTime0;
+ sendBack.sampleTimeEvent = sampleTimeEvent;
+ sendBack.deltaSec = deltaSec;
+ sendBack.cycleTime0 = cycleTime0;
+ sendBack.cycleTimeEvent = cycleTimeEvent;
+ cycleDelta = cycleTimeEvent - cycleTime0;
+ sendBack.cycleDelta = cycleDelta;
+
+
+ %% Calculation confirmation check
+ % Use the delta time (in seconds (or cycles) to confirm the sample
+ % number that was passed in
+ % Open issue, time resolution limit:
+ % Milisecond resoulution insufficient if sampling frequency is
+ % greater than 999 samples per SECOND
+ % Determine alloable error - resolution 1 milisec = x samples
+ % If x > 1, then time resolution insufficient to accurately check
+ sampleCheck = cycleDelta * ccTSSinTO.samplesPerCycle;
+ sampleError = ccTSSinTO.sample - sampleCheck; % Error in samples caused by milisec resolution
+ sendBack.sampleError = sampleError;
+
+ if (abs(sampleError) > maxMsecSampleError)
+ errorNote = ['Sample error greater than expected: ',num2str(sampleError) ...
+ ' 1 mSec resolution max sample error: ',num2str(maxMsecSampleError)];
+ sendBack.error3 = errorNote;
+ sendBack.goodData = false;
+ end
+
+end
+
+function PH60 = isIt60HzGen2SubFunction(mxHere,spc,lastN,iDat,vo,sensorGroup,thr_hz60)
+ howMany = length(mxHere);
+ PH60(howMany,4) = false; % PH1, PH2, PH3, col4/true = all phases are 60HZ
+ spchalf = round((spc/2),0); % for +/- 1/2 cycle calc
+ if strcmp(sensorGroup,'I123')
+ iCols = 1:3;
+ end
+ if strcmp(sensorGroup,'I456')
+ iCols = 4:6;
+ end
+ for hm = 1:howMany
+ mxStart = mxHere(hm) - spchalf;
+ mxEnd = mxHere(hm) + spchalf - 1;
+ % trap for start / end of file limits
+ if mxStart < 1
+ mxStart = 1;
+ mxEnd = mxStart + spc - 1;
+ end
+ if mxEnd > lastN
+ mxStart = lastN - spc + 1;
+ mxEnd = lastN;
+ end
+ % check if cycleX is 60 Hz
+ cycleX = iDat(mxStart:mxEnd,iCols);
+ normalizeIt = max(vo.iRMS1toEnd(mxStart:mxEnd,iCols)) * sqrt(2);
+ if max(normalizeIt) < 1
+ normalizeIt = [1, 1, 1]; % trap for small current
+ end
+ cycleXn = cycleX ./ normalizeIt;
+
+ % From Matlab fft example
+ L = spc; % Length of signal
+ w1 = cycleXn; % TODO - see if each phase needs to be checked!
+ Y = fft(w1);
+ P2 = abs(Y/L);
+ P1 = P2((1:L/2+1),:);
+ P1((2:end-1),:) = 2*P1((2:end-1),:);
+ at60 = P1(2,:); % 60HZ data point is the second
+ % Figure out if any single phase has 60 HZ
+
+ PH60(hm,1:3) = (at60 > thr_hz60);
+ PH60(hm,4) = all(PH60(hm,1:3));
+ end
+
+
+
+end
+
+function [mxColor, mxColorID] = p1_stateChangeColorMapV2SubFunction(sensorGroup,mxHere,vo,other)
+ mxColor = struct;
+ mxColorID = struct;
+ global currentFolder
+ % minimum current flow
+ minCurrentFlow = 1; % 1 amp RMS
+ lastN = vo.lastN;
+ spc = vo.spc;
+ mxPts = length(mxHere);
+ colorID = zeros(mxPts,4); % PH1, PH2, PH3, signal (3 phase equivalent)
+
+ path2 = strcat(currentFolder,'\colorIndex.txt')
+ gpaCI = importGPAcolorIntNestedFunction(path2); % gpaCI = GPA color integer
+
+
+% losCheck = false;
+% singlePhase = false;
+ % initialize color, all cases
+ clearColor = 'dkGrayTBD';
+ colorName = clearColorName(mxPts,clearColor);
+ colorID = assignColorIDs(colorName,gpaCI);
+ % voltage 3 phase sanity check
+ sanityColor = strings(mxPts,1);
+ sanityColor(:,1) = clearColor;
+% sanityColor2 = strings(mxPts,1);
+% sanityColor2(:,1) = clearColor;
+
+ % Assign colors - voltage cases
+ if (strcmp(sensorGroup,'V123') || strcmp(sensorGroup,'V456'))
+ iRnge = 1:3; % normal case, but MOS exception
+ [~, cx] = size(vo.iFault(1,:));
+ if ((cx == 6) && strcmp(sensorGroup,'V456'))
+ iRnge = 4:6; % when processing V456 and I4:6 exists
+ end
+ if strcmp(sensorGroup,'V123')
+ mxRange = 1:3;
+ signal = other.sig1;
+ end
+ if strcmp(sensorGroup,'V456')
+ mxRange = 4:6;
+ signal = other.sig2;
+ end
+ sigVals = signal(mxHere);
+
+ % Good source
+ thisColor = 'redSource';
+% thisIndex = vo.vGood(mxHere,mxRange);
+% thisIndex = [thisIndex, vo.vGood3PH(mxHere)];
+ thisIndex = (vo.vRMS1toEnd(mxHere,mxRange)/vo.nominalLG) > 0.9;
+ ti4 = thisIndex(:,1) & thisIndex(:,2) & thisIndex(:,3);
+ thisIndex = [thisIndex, ti4];
+ colorName(thisIndex) = thisColor;
+ % sanity check - good source
+ sanityIndex = sigVals > 2.75;
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info good source: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+ % PQ - no fault
+ thisColor = 'tanPQ';
+ thisIndex = vo.vPQ(mxHere,mxRange);
+ thisIndex = [thisIndex, vo.vPQ3PH(mxHere)];
+ colorName(thisIndex) = thisColor;
+ % sanity check - PQ no fault
+ sanityIndex = ((sigVals <= 2.75) & (sigVals > 0.4));
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info PQ no fault: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+ % PQ with fault present
+ thisColor = 'pinkFltPQ';
+ thisIndex = (vo.vPQ(mxHere,mxRange) & vo.iFault(mxHere,iRnge));
+ thisIndex2 = vo.vPQ3PH(mxHere) & vo.iFault3PH(mxHere);
+ thisIndex = [thisIndex, thisIndex2];
+ colorName(thisIndex) = thisColor;
+ % sanity check - PQ with fault
+ sanityIndex = ((sigVals <= 2.75) & (sigVals > 0.4) & vo.iFault3PH(mxHere));
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info PQ fault present: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+ % LOS test
+ thisColor = 'blackLOS';
+ thisIndex = vo.losAll(mxHere,mxRange);
+ if strcmp(sensorGroup,'V123')
+ thisIndex = [thisIndex, vo.los123V2(mxHere)];
+ end
+ if strcmp(sensorGroup,'V456')
+ thisIndex = [thisIndex, vo.los456V2(mxHere)];
+ end
+ colorName(thisIndex) = thisColor;
+ % sanity check - LOS test
+ sanityIndex = (sigVals <= 0.4);
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info LOS: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+ % Single phase over-ride (only applies to total)
+ thisColor = 'orgSglPH';
+ if strcmp(sensorGroup,'V123')
+ thisIndex(:,4) = vo.sglPh123(mxHere);
+ end
+ if strcmp(sensorGroup,'V456')
+ thisIndex(:,4) = vo.sglPh456(mxHere);
+ end
+ colorName(thisIndex) = thisColor;
+
+ % sanity check - singe phase test
+ sanityIndex = (sigVals > 0.4) & (sigVals <= 1.8);
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info single phase test: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+ % Add sanity check colors as column 5
+ colorName = [colorName, sanityColor];
+ colorID = assignColorIDs(colorName,gpaCI);
+ mxColor = colorName;
+ mxColorID = colorID;
+ return;
+ end % END Voltage
+
+ % Assign i colors - PCR current cases
+ % TODO SEL current cases!!!
+ if (strcmp(sensorGroup,'I123') && other.V123yes && other.V456yes)
+ mxRange = 1:3;
+ % Initialize to greenOpen to see if this improves logic flow
+ % Experiment to see how many false opens are created
+ thisColor = 'greenOpen';
+ tmp = ones(mxPts,4);
+ thisIndex = tmp > 0;
+ colorName(thisIndex) = thisColor;
+
+ % Good current (looking at the max phase)
+ thisColor = 'redCurrent';
+% thisIndex = vo.iGood(mxHere,mxRange);
+% thisIndex = [thisIndex, vo.iGood3PH(mxHere)];
+ thisRMS = vo.iRMS1toEnd(mxHere,:);
+ thisRMS(thisRMS < 0) = 0; % suppress negative RMS current
+ thisIndex = thisRMS > 1; % weak if i has DC offset
+ maxRMS = round(max(thisRMS,[],2),0);
+ thisIndex(:,4) = maxRMS > 3; % weak if i has DC offset
+ % amend index if current small and is 60HZ
+ smallI = (maxRMS <=3) & other.i123Is60HZ(:,4);
+ thisIndex(:,4) = thisIndex(:,4) | smallI; % 60HZ override small currents
+ colorName(thisIndex) = thisColor;
+ % VI+V analysis --- necessary for sanity checks
+ sig1x3 = other.sig1(mxHere);
+ sig2x3 = other.sig2(mxHere);
+ viplusv123 = (sig1x3 .* maxRMS) + sig1x3;
+ viplusv456 = (sig2x3 .* maxRMS) + sig2x3;
+ % sanity check - current is flowing
+ sanityIndex = (viplusv123 > 6) & (viplusv456 > 6);
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info has current flow: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+ % Test for pickup between 600 and 800 amps (highZ , high load)
+ thisColor = 'ltBluePickUp';
+ pickupYes = (vo.iRMS1toEnd(mxHere,mxRange) > 600) & ...
+ (vo.iRMS1toEnd(mxHere,mxRange) <= 800);
+ thisIndex = [pickupYes, any(pickupYes,2)];
+ colorName(thisIndex) = thisColor;
+
+ % Test for fault for png
+ thisColor = 'blueFault800';
+ faultYes = (vo.iRMS1toEnd(mxHere,mxRange) > 800);
+ thisIndex = [faultYes, any(faultYes,2)];
+ colorName(thisIndex) = thisColor;
+
+ % Test for open (no current and not LOS both sides)
+ % Careful, messes with your mind
+ thisColor = 'greenOpen';
+ notLOS = (~vo.vLOS(mxHere,1:3) & ~vo.vLOS(mxHere,4:6));
+ openCheck123 = vo.iNot(mxHere,mxRange) & notLOS;
+ thisIndex = [openCheck123, all(openCheck123,2)];
+ colorName(thisIndex) = thisColor;
+ % sanity check - current is not flowing
+ s1yes = other.sig1(mxHere) > 0.4;
+ s2no = other.sig2(mxHere) <= 0.4;
+ s2yes = other.sig2(mxHere) > 0.4;
+ s1no = other.sig1(mxHere) <= 0.4;
+ sanityIndex = ((s1yes & s2no) | (s1no & s2yes)) & smallI; % one good source, one bad source and low I not 60HZ
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info Open detected: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+
+
+ % Test for no source both directions, force current blackLOS
+ % May tend to mask mis-opeartion, only care if misOp
+ % Is later assigned a different color
+ thisColor = 'blackLOS';
+ noSrc = vo.vLOS(mxHere,1:3) & vo.vLOS(mxHere,4:6);
+ thisIndex = [noSrc, all(noSrc,2)];
+ colorName(thisIndex) = thisColor;
+ % sanity check - total LOS
+% sanityIndex = ((other.sig1(mxHere) <= 0.4) & (other.sig2(mxHere) <= 0.4));
+ sanityIndex = s1no & s2no;
+ sanityColor(sanityIndex) = thisColor;
+ sanityCheck = strcmp(colorName(:,4),sanityColor(:));
+ if all(sanityCheck)
+ disp('Debug info Open LOS: colorName4 matches sanityColor');
+ %else
+ %callOutDifferences(mxHere,sanityCheck,colorName(:,4),sanityColor(:,1),sigVals)
+ end
+
+ % COLUMN #4 analysis -- leave individual phases untouched
+ % Test for protection trip toward V456
+ % Requires an open after a fault
+ % mxPts >= 2 (can't compare a single data point)
+ if mxPts >= 2 && (any(strcmp(colorName(:,4),'blueFault800')) || any(strcmp(colorName(:,4),'ltBluePickUp')))
+ V123src = ~(vo.vLOS(mxHere,1) & vo.vLOS(mxHere,2) & vo.vLOS(mxHere,3));
+ V456los = vo.vLOS(mxHere,4) & vo.vLOS(mxHere,5) & vo.vLOS(mxHere,6);
+ didTrip = testForProtectionTrip456(mxPts,colorName(:,4),V123src,V456los);
+ colorName(:,4) = didTrip;
+ end
+
+ % COLUMN #4 analysis -- leave individual phases untouched
+ % Test for protection trip toward V123
+ % Requires an open after a fault
+ if mxPts >= 2 && (any(strcmp(colorName(:,4),'blueFault800')) || any(strcmp(colorName(:,4),'ltBluePickUp')))
+ V123los = vo.vLOS(mxHere,1) & vo.vLOS(mxHere,2) & vo.vLOS(mxHere,3);
+ V456src = ~(vo.vLOS(mxHere,4) & vo.vLOS(mxHere,5) & vo.vLOS(mxHere,6));
+ didTrip = testForProtectionTrip123(mxPts,colorName(:,4),V123los,V456src);
+ colorName(:,4) = didTrip;
+ end
+
+ % COLUMN #4 analysis -- leave individual phases untouched
+ % Test for mis-operation
+ % Fault precedes no source both sides
+ if mxPts >= 2 && (any(strcmp(colorName(:,4),'blueFault800')) || any(strcmp(colorName(:,4),'ltBluePickUp')))
+ V123los = vo.vLOS(mxHere,1) & vo.vLOS(mxHere,2) & vo.vLOS(mxHere,3);
+ V456los = vo.vLOS(mxHere,4) & vo.vLOS(mxHere,5) & vo.vLOS(mxHere,6);
+ misOp = testForMisOperation(mxPts,colorName(:,4),V123los,V456los);
+ colorName(:,4) = misOp;
+ end
+ % Add sanity color and return
+ colorName = [colorName,sanityColor];
+ colorID = assignColorIDs(colorName,gpaCI);
+ mxColor = colorName;
+ mxColorID = colorID;
+ return;
+ end % end PCR current
+
+ % Assign i colors - SEL I123 current cases
+ % TODO SEL/MOS I456 current cases!!!
+% var = 'i have not entered loop'
+% if (strcmp(sensorGroup,'I123') && other.V123yes && ~other.V456yes)
+% var = 'i have entered loop'
+% mxRange = 1:3;
+%
+% % sanity, confirm CB has source (used for a couple cases)
+% sanityIndexHasSource = ((min(vo.vRMS1toEnd(mxHere,mxRange),[],2))/vo.nominalLG) > 0.1; % worst phase not zero
+% % Open check - CTs are accurate,
+% % so a 1 amp threshold should be a good test
+% thisColor = 'greenOpen';
+% thisRMS = vo.iRMS1toEnd(mxHere,:);
+% thisRMS(thisRMS < 0) = 0; % suppress negative RMS current
+% thisRMS = round(thisRMS,0);
+% thisIndex = thisRMS < 1; % weak if i has DC offset
+% thisIndex(:,4) = any(thisIndex,2);
+% colorName(thisIndex) = thisColor;
+% % Sanity check, has source and no current
+% sanityIndex = thisIndex(:,4) & sanityIndexHasSource;
+% sanityColor(sanityIndex) = thisColor;
+%
+%
+% % Good current (looking at the max phase)
+% thisColor = 'redCurrent';
+% thisIndex = thisRMS > 1; % weak if i has DC offset
+% %maxRMS = round(max(thisRMS,[],2),0);
+% thisIndex(:,4) = maxRMS > 1; % weak if i has DC offset
+% colorName(thisIndex) = thisColor;
+%
+% sanityIndex = sanityIndexHasSource & thisIndex(:,4); % has voltage and current
+% sanityColor(sanityIndex) = thisColor;
+%
+% % Test for pickup between 600 and 800 amps (highZ , high load)
+% thisColor = 'ltBluePickUp';
+% pickupYes = (vo.iRMS1toEnd(mxHere,mxRange) > 600) & ...
+% (vo.iRMS1toEnd(mxHere,mxRange) <= 800);
+% thisIndex = [pickupYes, any(pickupYes,2)];
+% colorName(thisIndex) = thisColor;
+%
+% % Test for fault
+% thisColor = 'blueFault800';
+% faultYes = (vo.iRMS1toEnd(mxHere,mxRange) > 800);
+% thisIndex = [faultYes, any(faultYes,2)];
+% colorName(thisIndex) = thisColor;
+%
+% % Test for LOS
+% thisColor = 'blackLOS';
+% thisIndex = (vo.vRMS1toEnd(mxHere,mxRange)/vo.nominalLG) <= 0.1; % no source
+% thisIndex = [thisIndex, all(thisIndex,2)];
+% colorName(thisIndex) = thisColor;
+% % sanity check - total LOS
+% sanityIndex = ~sanityIndexHasSource;
+% sanityColor(sanityIndex) = thisColor;
+%
+% % COLUMN #4 analysis -- leave individual phases untouched
+% % Test for protection trip toward Load
+% % Requires an open after a fault
+% % mxPts >= 2 (can't compare a single data point)
+% if mxPts >= 2 && (any(strcmp(colorName(:,4),'blueFault800')) || any(strcmp(colorName(:,4),'ltBluePickUp')))
+% didTrip = CBtestForProtectionTrip(mxPts,colorName(:,4),sanityIndexHasSource);
+% colorName(:,4) = didTrip;
+% end
+%
+% % Add sanity color and return
+% colorName = [colorName,sanityColor];
+% colorID = assignColorIDs(colorName,gpaCI);
+% mxColor = colorName;
+% mxColorID = colorID;
+% return;
+% end
+
+function configreplayGPAcolorIndex = importGPAcolorIntNestedFunction(filename, dataLines)
+if nargin < 2
+ dataLines = [2, Inf];
+end
+
+%% Setup the Import Options and import the data
+opts = delimitedTextImportOptions("NumVariables", 5);
+
+% Specify range and delimiter
+opts.DataLines = dataLines;
+opts.Delimiter = "\t";
+
+% Specify column names and types
+opts.VariableNames = ["GPAint", "Color", "Red", "Green", "Blue"];
+opts.VariableTypes = ["double", "string", "double", "double", "double"];
+
+% Specify file level properties
+opts.ExtraColumnsRule = "ignore";
+opts.EmptyLineRule = "read";
+
+% Specify variable properties
+opts = setvaropts(opts, "Color", "WhitespaceRule", "preserve");
+opts = setvaropts(opts, "Color", "EmptyFieldRule", "auto");
+
+% Import the data
+configreplayGPAcolorIndex = readtable(filename, opts);
+
+end
+
+end
+
+
+
+function colorName = clearColorName(mxPts,clearColor)
+ colorName = strings(mxPts,4); % PH1, PH2, PH3, signal (3 phase equivalent)
+ colorName(:,:) = clearColor;
+ % call to find ID
+end
+
+function colorID = assignColorIDs(cNames,gpaCI)
+ [r, c] = size(cNames);
+ colorID = zeros(r,c);
+ for rix = 1:r
+ for cix = 1:c
+ gpaRowI1 = strcmp(gpaCI.Color,cNames(rix,cix));
+ colorID(rix,cix) = gpaCI.GPAint(gpaRowI1);
+ end
+ end
+end
+
+
+function didTrip = testForProtectionTrip456(mxPts,colorName4,V123src,V456los)
+ didTrip = colorName4; % return unmodified if did not trip
+ for m = 1:mxPts-1
+ if strcmp(colorName4(m),'blueFault800') || strcmp(colorName4(m),'ltBluePickUp')
+ if V123src(m+1) && V456los(m+1)
+ didTrip(m+1) = 'greenTrip';
+ end
+ end
+ end
+end
+
+
+function didTrip = testForProtectionTrip123(mxPts,colorName4,V123los,V456src)
+ didTrip = colorName4; % return unmodified if did not trip
+ for m = 1:mxPts-1
+ if strcmp(colorName4(m),'blueFault800') || strcmp(colorName4(m),'ltBluePickUp')
+ if V123los(m+1) && V456src(m+1)
+ didTrip(m+1) = 'greenTrip';
+ end
+ end
+ end
+end
+
+function misOp = testForMisOperation(mxPts,colorName4,V123los,V456los)
+ misOp = colorName4; % return unmodified if did not trip
+ for m = 1:mxPts-1
+ if strcmp(colorName4(m),'blueFault800') || strcmp(colorName4(m),'ltBluePickUp')
+ if V123los(m+1) && V456los(m+1)
+ misOp(m+1) = 'blackLOS';
+ end
+ end
+ end
+end
+
+function didTrip = CBtestForProtectionTrip(mxPts,colorName4,sanityIndexHasSource)
+ didTrip = colorName4;
+ for m = 1:mxPts-1
+ if strcmp(colorName4(m),'blueFault800') || strcmp(colorName4(m),'ltBluePickUp')
+ if strcmp(colorName4(m+1),'greenOpen') && sanityIndexHasSource(m+1)
+ didTrip(m+1) = 'greenTrip';
+ end
+ end
+ end
+end
+function configreplayGPAcolorIndex = importGPAcolorIntSubFunction(filename, dataLines)
+if nargin < 2
+ dataLines = [2, Inf];
+end
+
+% Setup the Import Options and import the data
+opts = delimitedTextImportOptions("NumVariables", 5);
+
+% Specify range and delimiter
+opts.DataLines = dataLines;
+opts.Delimiter = "\t";
+
+% Specify column names and types
+opts.VariableNames = ["GPAint", "Color", "Red", "Green", "Blue"];
+opts.VariableTypes = ["double", "string", "double", "double", "double"];
+
+% Specify file level properties
+opts.ExtraColumnsRule = "ignore";
+opts.EmptyLineRule = "read";
+
+% Specify variable properties
+opts = setvaropts(opts, "Color", "WhitespaceRule", "preserve");
+opts = setvaropts(opts, "Color", "EmptyFieldRule", "auto");
+
+% Import the data
+configreplayGPAcolorIndex = readtable(filename, opts);
+
+end
+
+function sb = p1_stateChangeDataLogV2SubFunction(action,inLog,newRecords,Circuit,Phase,Orientation,wfCfg)
+ global currentFolder
+ sb = struct;
+
+
+ if strcmp(action,'getDefaults')
+ sb.default = 'set';
+ sb.actionList = {'getDefaults','getDataTypes','newFile','setCommonValues','addRecord','addRecToDatabase','writeTaskListToDB'};
+ sb.addToDB = false; % if true, attempts to add records to database
+ % column names for data record to be logged
+ % divided into groups to allow 1 to N data values per sensor channel
+ taskInfo = {'EventID', ... % keys and sorting
+ 'SOE_ID', ... % GPA SOE_groupID?
+ 'Circuit', ...
+ 'DeviceName', ...
+ 'ChannelName', ...
+ 'SOEdateTimeLocal', ...
+ 'systemVoltage'}; % Expected power flow direction
+
+
+ mv1toN = { 'mxNum', ... % measurement number (typically 1 to 3)
+ 'mxHereSamp', ...
+ 'mxTimeLocal', ...
+ 'mxValue', ...
+ 'mxColor', ... % Human color name
+ 'mxColorMapInt'};
+
+ linkInfo = {'PlotFileName','IncidentID'};
+ colNames = [taskInfo, mv1toN, linkInfo];
+ sb.colNames = colNames;
+ sb.colValue = cell2struct(colNames,colNames,2); % data record
+ sb.mv1toN = cell2struct(mv1toN,mv1toN,2); % measured values data set
+ return;
+ end % END initialization
+
+
+ if strcmp(action,'getDataTypes')
+
+ intList = {'EventID','SOE_ID','mxNum','mxHereSamp','mxColorMapInt', ...
+ 'IncidentID'};
+
+ floatList = {'systemVoltage','mxValue'};
+
+ dateList = {'SOEdateTimeLocal','mxTimeLocal'};
+
+ textList = {'Circuit','DeviceName','ChannelName','mxColor'};
+ bigTextList = {'PlotFileName'};
+ pkList = {'EventID','DeviceName','ChannelName','mxHereSamp'};
+ sb.intList = intList;
+ sb.floatList = floatList;
+ sb.dateList = dateList;
+ sb.textList = textList;
+ sb.bigTextList = bigTextList;
+ sb.pkList = pkList;
+ sb.lastColumn = lastColumn;
+ return;
+ end % END getDataTypes
+
+ %% Create file and write column names
+ if strcmp(action,'newFile')
+ path3 = strcat(currentFolder,'\Output\SOE_Log.txt')
+ fOutId = fopen(path3,'a+'); % open file
+ [~,maxCol] = size(inLog.colNames);
+ for colX = 1:maxCol-1
+ fprintf(fOutId,'%s\t',string(inLog.colNames(colX)));
+ end
+ fprintf(fOutId,'%s\n',string(inLog.colNames(maxCol))); %terminate row with new line
+ fclose(fOutId);
+ return; % nothing sent back, no data in "inLog" yet
+ end % END first row
+
+ %% Set common values
+ %
+ if strcmp(action,'setCommonValues')
+ sb = inLog; % must preserve what was passed in
+ cv = inLog.colValue; % local copy to reduce struct name size
+ cv.EventID = wfCfg.eventID;
+ cv.SOE_ID = wfCfg.soeID;
+ cv.Circuit = Circuit;
+ cv.DeviceName = wfCfg.recording_device;
+ cv.SOEdateTimeLocal = wfCfg.soeTime;
+ voltagelevel = extract(cv.Circuit,4);
+ voltagelevel = char(voltagelevel);
+ if voltagelevel == '2'
+ cv.systemVoltage = '12 kV';
+ elseif voltagelevel == '4'
+ cv.systemVoltage = '46 kV';
+ else
+ cv.systemVoltage = '4 kV';
+ end
+ cv.IncidentID = wfCfg.incidentID;
+ sb.colValue = cv; % send back assigned values
+ return;
+ end
+
+
+
+
+ %% Append file with values measured by sensors
+ % log all other process data as name - value pairs
+ % need to loop and write all GBB results
+ if strcmp(action,'addRecord')
+ sb = inLog; % must preserve what was passed in
+ addRows = newRecords.addRows;
+ useCol = newRecords.useCol;
+ valsIn = newRecords.valsIn;
+ if addRows < 1 % nothing to log
+ return;
+ end
+ % build a structure of data points
+ newRec = struct([]);
+ for i = 1:addRows
+ thisRow = inLog.colValue;
+ %thisRow.SOEdateTimeLocal = thisTask.DateTimeSOE;
+ %thisRow.systemVoltage = thisTask.VoltClassLL;
+ thisRow.mxNum = i;
+ thisRow.mxHereSamp = newRecords.mxHere(i);
+ thisRow.mxTimeLocal = char(datetime(valsIn.mxHereTime(i),'Format','yyyy-MM-dd HH:mm:ss.SSS'));
+ %thisRow.mxTimeLocal = char(datetime(valsIn.mxHereTime(i),'Format','yyyy-MM-dd HH:mm:ss.SSS') - hours(5));
+ thisRow.mxValue = newRecords.signal(i);
+ thisRow.mxColor = newRecords.mxColor(i,useCol);
+ thisRow.mxColorMapInt = newRecords.mxColorMapInt(i,useCol);
+ if i == 1
+ newRec = thisRow; % forces newRec to have same structure as thisRow
+ end
+ newRec(i) = thisRow;
+ end
+ path4 = strcat(currentFolder,'\Output\SOE_Log.txt')
+ writetable(struct2table(newRec),path4,'Delimiter','\t','WriteMode','Append'); % note: fields must be scalar
+ return;
+
+ return;
+ end
+
+end
+
+function sb = p1_voltSensorReferenceSubFunction(wfCfg,Vmatrix,Imatrix)
+ sb = struct; % sb abbreviation for sendBack
+ sb.changes = 0; % case 3 sensors and no changes
+ sb.chPts = -1;
+
+ % Vector analysis, waveforms and rms calculations
+ intoVPQMVI.default = 'getDefaults';
+ intoVPQMVI = ccVectorPQmatrixVISubFunction(intoVPQMVI,wfCfg,Vmatrix,Imatrix);
+ vo = ccVectorPQmatrixVISubFunction(intoVPQMVI,wfCfg,Vmatrix,Imatrix);
+
+ signalPerPhase = vo.vRMS1toEnd;
+ signalPU = signalPerPhase / vo.nominalLG;
+ attempt1sig1 = sum(signalPU(:,1:3),2); % superceded by deviation
+ sb.attempt1sig1 = attempt1sig1;
+ % logic change, 3PH equivalent, less relative deviation
+ V123rmsAdd = round((sum(vo.vRMS1toEnd(:,1:3),2)/vo.nominalLG),2);
+ relDev = abs(vo.vRMS1toEnd(:,1:3) - vo.nominalLG)/vo.nominalLG;
+ V123relDev = round(sum(relDev,2),2);
+ sig1 = V123rmsAdd - V123relDev;
+ sig1(sig1<0) = 0; % Avoid negative calculations
+ changeHere1 = findchangepts(sig1,'Statistic','mean','MaxNumChanges',2);
+ sig1DidChange = true;
+ sb.sig1 = sig1;
+ sb.sig2 = -1; % mitigate crash if only 3 sensors
+ if isempty(changeHere1)
+ sig1DidChange = false;
+ sb.changes = 0; % case 3 sensors and no changes
+ sb.chPts = -1;
+ % NOTE: calling function must trap and ingnore
+ elseif length(changeHere1) == 2
+ changeHere1 = samePoint(changeHere1);
+ sb.changes = length(changeHere1); % case 3 sensors
+ sb.chPts = changeHere1;
+ end
+
+ if vo.vsTotal == 6
+ attempt1sig2 = sum(signalPU(:,4:6),2); % superceded by deviation
+ sb.attempt1sig2 = attempt1sig2;
+ % logic change, 3PH equivalent, less relative deviation
+ V456rmsAdd = round((sum(vo.vRMS1toEnd(:,4:6),2)/vo.nominalLG),2);
+ relDev = abs(vo.vRMS1toEnd(:,4:6) - vo.nominalLG)/vo.nominalLG;
+ V456relDev = round(sum(relDev,2),2);
+ sig2 = V456rmsAdd - V456relDev;
+ sig2(sig2<0) = 0; % Avoid negative calculations
+ sb.sig2 = sig2;
+ VxVyOpenDetect = abs(sig2 - sig1);
+ isItOpen = (VxVyOpenDetect > (5/100));
+ % Simple check for trip (or open with two different sources)
+ if sum(isItOpen) > 90
+ itIsOpen = true;
+ else
+ itIsOpen = false; % or open with two different sources
+ end
+ sb.itIsOpen = itIsOpen;
+ changeHere2 = findchangepts(sig2,'Statistic','mean','MaxNumChanges',2); % change points
+ sig2DidChange = true;
+ if isempty(changeHere2)
+ sig2DidChange = false;
+ elseif length(changeHere2) == 2
+ changeHere2 = samePoint(changeHere2);
+ end
+
+ % Determine the number of changes, and which ones to use
+ if sig1DidChange && sig2DidChange
+ % confirm one or both are useful signals
+ usefulSig1 = usefulSignal(sig1);
+ usefulSig2 = usefulSignal(sig2);
+ % abort if neither is useful
+ if ~usefulSig1 && ~usefulSig2
+ sb.changes = 0;
+ sb.chPts = -1;
+ return;
+ end
+ % Use sig1 because sig2 is not useful
+ if usefulSig1 && ~usefulSig2
+ sb.changes = length(changeHere1);
+ sb.chPts = changeHere1;
+ return;
+ end
+ % Use sig2 because sig1 is not useful
+ if ~usefulSig1 && usefulSig2
+ sb.changes = length(changeHere2);
+ sb.chPts = changeHere2;
+ return;
+ end
+ % Both signals are useful, several cases need to be examined
+ % Case 1: single change each, is it the same point?
+ if ((length(changeHere1) == 1) && (length(changeHere2) == 1))
+ % merge change if approx same point
+ changeHere = [changeHere1; changeHere2];
+ changeHere = samePoint(changeHere);
+ sb.changes = length(changeHere);
+ sb.chPts = changeHere;
+ return;
+ end
+ % Case 2: V123 has 2 changes, V456 has 1 change, ignore V456
+ % TODO, find exmaple case and determine if min and max is better
+ if ((length(changeHere1) == 2) && (length(changeHere2) == 1))
+ commonFlag = confirmCommonPoint(changeHere1,changeHere2);
+ if ~commonFlag
+ logMe = "Case 2: Two signals missing a common change point";
+ disp(logMe);
+ end
+ % Use V123 changes
+ sb.changes = length(changeHere1);
+ sb.chPts = changeHere1;
+ return;
+ end
+ % Case 3: V456 has 2 changes, V123 has 1 change, ignore V123
+ % TODO, find exmaple case and determine if min and max is better
+ if ((length(changeHere1) == 1) && (length(changeHere2) == 2))
+ commonFlag = confirmCommonPoint(changeHere1,changeHere2);
+ if ~commonFlag
+ logMe = "Case 3: Two signals missing a common change point";
+ disp(logMe);
+ end
+ % Use V123 changes
+ sb.changes = length(changeHere2);
+ sb.chPts = changeHere2;
+ return;
+ end
+ % Case 4: both have 2 changes, are they similar points?
+ % See test data for case 4 in comments at end of file
+ if ((length(changeHere1) == 2) && (length(changeHere2) == 2))
+ commonFlag = confirmCommonPoint(changeHere1,changeHere2);
+ if ~commonFlag
+ logMe = "Case 4: Two signals missing a common change point";
+ disp(logMe);
+ end
+ % check if approx same point
+ changeHereX = [changeHere1(1); changeHere2(1)];
+ changeHereX = samePoint(changeHereX);
+ changeHereY = [changeHere1(2); changeHere2(2)];
+ changeHereY = samePoint(changeHereY);
+ changeHere = [changeHereX; changeHereY];
+ changeHere = samePoint(changeHere);
+ % Assume points between min and max are transients
+ if length(changeHere) > 2
+ changeHere = [min(changeHereX);max(changeHereY)];
+ end
+ sb.changes = length(changeHere);
+ sb.chPts = changeHere;
+ return;
+ end
+ end
+ end
+
+end
+
+function sb = samePoint(changeHere)
+ sb = changeHere; % assume different points
+
+ howClose = abs(diff(changeHere));
+ if howClose <= 90
+ sb = round((sum(changeHere)/2),0);
+ end
+end
+
+function sb = usefulSignal(sigPU)
+ sb = false;
+ minChange = 0.15; % in PU
+ minSignal = 0.5; % in PU
+
+ someValue = (sigPU > minSignal);
+ howMany = sum(someValue);
+
+ maxLessMin = abs(max(sigPU)) - abs(min(sigPU));
+
+ if (howMany > 90) && (maxLessMin > minChange)
+ sb = true;
+ end
+end
+
+function sb = confirmCommonPoint(changeSet1,changeSet2)
+ sb = false;
+ sameFirst = false;
+ sameLast = false;
+ commonPoint = false;
+
+ firstCheck = samePoint([changeSet1(1);changeSet2(1)]);
+ if length(firstCheck) == 1
+ sameFirst = true;
+ end
+ lastCheck = samePoint([changeSet1(end);changeSet2(end)]);
+ if length(lastCheck) == 1
+ sameLast = true;
+ end
+ if (length(changeSet1) == 2) && (length(changeSet2) == 2)
+ firstLast = samePoint([changeSet1(1);changeSet2(2)]);
+ if length(firstLast) == 1
+ commonPoint = true;
+ end
+ lastFirst = samePoint([changeSet1(2);changeSet2(1)]);
+ if length(lastFirst) == 1
+ commonPoint = true;
+ end
+ end
+ sb = any([sameFirst, sameLast, commonPoint]);
+end
+
+function classificationGBB1 = importGBBlistFile150SubFunction(filename, startRow, endRow)
+
+delimiter = '\t';
+if nargin<=2
+ startRow = 2;
+ endRow = inf;
+end
+
+formatSpec = '%s%s%s%s%s%s%s%s%f%s%s%s%s%s%[^\n\r]';
+
+
+fileID = fopen(filename,'r');
+
+dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', delimiter, 'TextType', 'string', 'HeaderLines', startRow(1)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n');
+for block=2:length(startRow)
+ frewind(fileID);
+ dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', delimiter, 'TextType', 'string', 'HeaderLines', startRow(block)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n');
+ for col=1:length(dataArray)
+ dataArray{col} = [dataArray{col};dataArrayBlock{col}];
+ end
+end
+
+fclose(fileID);
+
+classificationGBB1 = table(dataArray{1:end-1}, 'VariableNames', {'GBBid','Active','Group','Bucket','Bin','OperatingDevice','Outcome','Revision','TestCount','TestResult','ResultDeterminedByFunction','TestConflict','TBD','Other'});
+
+end
+
+function Vmatrix = OrientationCheck(Vmatrix, Orientation)
+ if strcmp('YX',Orientation)
+ Vmatrix_X = Vmatrix(1:3,:);
+ Vmatrix_Y = Vmatrix(4:6,:);
+ Vmatrix = vertcat(Vmatrix_Y,Vmatrix_X);
+ end
+return
+end
\ No newline at end of file
diff --git a/Intellirupters/toGPA_G7_Replay/MakeReplay.m b/Intellirupters/toGPA_G7_Replay/MakeReplay.m
new file mode 100644
index 0000000..f2982da
--- /dev/null
+++ b/Intellirupters/toGPA_G7_Replay/MakeReplay.m
@@ -0,0 +1,206 @@
+%Austin Replay
+%Purpose of this script is to generate a replay text file to pass to
+%Stephen at GPA so he can integrate into SOE Engine
+
+function MakeReplay(Setting)
+ text_file = Setting.SOELogPath;
+ TSx = 1;
+ NLT_Array = [];
+ fid = fopen(text_file, 'rt');
+ datacell = textscan(fid, '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s', 'delimiter', '\t', 'HeaderLines', 1);
+ fclose(fid);
+ cycle = 1/60;
+ %compiling columns from tsv file generated by AustinG7
+ SOE_ID = datacell{2};
+ Event_ID = datacell{1};
+ Circuit = datacell{3};
+ DeviceName = datacell{4};
+ ChannelName = datacell{5};
+ SOEdateTimeLocal = datacell{6};
+ mxTimeLocal = datacell{10};
+ mxColorMapInt = datacell{13};
+
+ SensorName = strcat(Circuit,'-',DeviceName,'.',ChannelName);
+
+ TempArray = [SensorName,mxTimeLocal,mxColorMapInt,SOE_ID,Event_ID];
+ MasterArray = [];
+ for jj = 1:length(TempArray(:,1))
+ if str2double(TempArray{jj,4}) == Setting.SOE_ID
+ MasterArray = vertcat(MasterArray, TempArray(jj,:));
+ end
+ end
+ if length(MasterArray) == 0
+ return
+ end
+ MasterArray = sortrows(MasterArray,2);
+
+ StartTime = datetime(MasterArray(1,2),'Format','yyyy-MM-dd HH:mm:ss.SSS') - seconds(0.010);
+ EndTime = datetime(MasterArray(end,2),'Format','yyyy-MM-dd HH:mm:ss.SSS') + seconds(0.010);
+ TimeLength = between(StartTime,EndTime);
+ TimeLength = time(TimeLength);
+ NewTimeArray = unique(vertcat(StartTime, MasterArray(:,2), EndTime));
+
+ %need to find number of devices present
+ uniqueSensors = unique(SensorName);
+ unq = size(unique(SensorName));
+ NoOfDevices = unq(1);
+
+ %time slots and duration of SOE event
+ format = "hh:mm:ss.SSSS";
+ secs = string(TimeLength,format);
+ secs = second(datetime(secs));
+ milliseconds = 1000*secs;
+ TimeSlots = round(milliseconds / TSx);
+
+
+ %make an array containing all the time slots (one for each millisecond)
+ base = 0;
+ oldSensor = '';
+ for jj = 1:length(uniqueSensors(:,1))
+ NewTime = StartTime;
+
+ %creating sensor order numbers required for replay
+ SensorOrder = split(uniqueSensors(jj,1),'.');
+ SensorOrderNew = SensorOrder(1,1);
+ if ~strcmp(oldSensor,SensorOrderNew)
+ base = base + 100;
+ end
+ oldSensor = SensorOrderNew;
+ SensorOrder2 = SensorOrder(2,1);
+ if strcmp(SensorOrder2,'V123')
+ digit = base + 1;
+ elseif strcmp(SensorOrder2,'I123')
+ digit = base + 2;
+ else
+ digit = base + 3;
+ end
+
+
+
+ for ii = 1:length(NewTimeArray)
+ %NewTime = NewTime + seconds(0.001);
+ timeForArray = string(NewTimeArray(ii,1));
+ sensorForArray = string(uniqueSensors(jj));
+ t11 = datevec(datenum(NewTimeArray(1,1)));
+ t22 = datevec(datenum(NewTimeArray(ii,1)));
+ elapsedMS = (etime(t22,t11)*1000);
+ elapsedSECS = floor(elapsedMS / 1000);
+ elapsedCYCLES = floor(elapsedMS / (cycle*1000));
+
+ if ii - 1 == 0
+ t33 = t11;
+ else
+ t33 = datevec(datenum(NewTimeArray(ii-1,1)));
+ end
+ t44 = datevec(datenum(NewTimeArray(ii,1)));
+ timeGAP_MS = (etime(t44,t33)*1000);
+
+ NLT_Array_NewRow = [sensorForArray digit ii timeForArray 'dummy' elapsedMS elapsedSECS elapsedCYCLES timeGAP_MS];
+ NLT_Array = vertcat(NLT_Array, NLT_Array_NewRow);
+ end
+ end
+
+ %moving colors over to new array from existing array
+ for xx = 1:length(NLT_Array(:,1))
+ for yy = 1:length(MasterArray(:,1))
+ if strcmp(NLT_Array(xx,1), MasterArray(yy,1)) && strcmp(NLT_Array(xx,4), MasterArray(yy,2))
+ NLT_Array(xx,5) = MasterArray(yy,3);
+ end
+ end
+ end
+
+ %filling in new array's missing color gaps
+ for zz = 1:length(uniqueSensors(:,1))
+ mxColor_ID = 0;
+ for aa = 1:length(NLT_Array(:,1))
+ if strcmp(uniqueSensors(zz,1), NLT_Array(aa,1))
+ test = (ismissing(NLT_Array(aa,5)) | strcmp(NLT_Array(aa,5),'dummy'));
+ if test
+ NLT_Array(aa,5) = mxColor_ID;
+ else
+ mxColor_ID = NLT_Array(aa,5);
+ end
+ end
+ end
+ end
+
+ %% Here we will add the additional columns needed for the replay
+ %adding SensorTypeID
+ array_length = size(NLT_Array,1);
+ for jj = 1:array_length
+ tf = contains(NLT_Array(jj,1),'I123');
+ if tf
+ SensorTypeID(jj,1) = 2;
+ else
+ SensorTypeID(jj,1) = 1;
+ end
+ end
+ NLT_Array = horzcat(SensorTypeID, NLT_Array);
+
+ %% Here we will add an additional column for NLTDataTypeID which is always 1
+ %adding NLTDataTypeID
+ for jj = 1:array_length
+ NLTDataTypeID(jj,1) = 1;
+ end
+ NLT_Array = horzcat(NLTDataTypeID, NLT_Array);
+
+ %% Here we will add EventID as an additional column
+ for jj = 1:array_length
+ NLTEventID_column(jj,1) = "-1";
+ for ii = 1:length(MasterArray(:,1))
+ if strcmp(NLT_Array(jj,3), MasterArray(ii,1)) && strcmp(NLT_Array(jj,6), MasterArray(ii,2))
+ NLTEventID_column(jj,1) = MasterArray(ii,5);
+ end
+ end
+ end
+ NLT_Array = horzcat(NLTEventID_column, NLT_Array);
+
+ %% Here we will add the TSxUnits which will be only in milliseconds to avoid losses
+ for jj = 1:array_length
+ TSxUnits(jj,1) = "mSec";
+ end
+ NLT_Array = horzcat(TSxUnits, NLT_Array);
+
+ %% Here we will add the TSx which will always be 1 milliseconds
+ for jj = 1:array_length
+ TSx(jj,1) = "1";
+ end
+ NLT_Array = horzcat(TSx, NLT_Array);
+
+ %% Here we will add the SOE ID
+ for jj = 1:array_length
+ SOEID_column(jj,1) = Setting.SOE_ID;
+ end
+ NLT_Array = horzcat(SOEID_column, NLT_Array);
+
+ %% Now we rearrange the Sensor Names to match what device names
+ for i = 1:length(uniqueSensors)
+ if length(split(uniqueSensors(i,1),'-')) > 2
+ rearrange = split(uniqueSensors(i,1),'-');
+ rearrange2 = split(rearrange(3,1),'.');
+ NewSensorName = rearrange(1,1) + "-" + rearrange2(1,1) + "-" + rearrange(2,1) + '.' + rearrange2(2,1);
+ for j = 1:height(NLT_Array)
+ NLT_Array(j,7);
+ uniqueSensors(i,1);
+ if strcmp(NLT_Array(j,7), uniqueSensors(i,1))
+ NLT_Array(j,7) = NewSensorName;
+
+ end
+ end
+ end
+ end
+
+ %% Here we add the map display - currents show by default
+ for i = 1:height(NLT_Array)
+ if contains(NLT_Array(i,7), 'I123')
+ Display(i,1) = '1';
+ else
+ Display(i,1) = '0';
+ end
+ end
+ NLT_Array = horzcat(NLT_Array, Display);
+
+ pathway = Setting.ReplayPath;
+ writematrix(NLT_Array,pathway,'Delimiter','\t');
+end
+
diff --git a/Intellirupters/toGPA_G7_Replay/MakeReplay.prj b/Intellirupters/toGPA_G7_Replay/MakeReplay.prj
new file mode 100644
index 0000000..0dc7074
--- /dev/null
+++ b/Intellirupters/toGPA_G7_Replay/MakeReplay.prj
@@ -0,0 +1,139 @@
+
+
+ MakeReplay
+
+
+ 1.0
+
+
+
+
+
+
+
+ \MakeReplay\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\MakeReplay\for_testing
+ ${PROJECT_ROOT}\MakeReplay\for_redistribution_files_only
+ ${PROJECT_ROOT}\MakeReplay\for_redistribution
+ ${PROJECT_ROOT}\MakeReplay
+ false
+
+ subtarget.net.component
+
+ MakeReplay
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ MakeReplay
+ Analytic
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G7_Replay
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\MakeReplay.m
+
+
+
+
+ ${PROJECT_ROOT}\MakeReplay.m
+
+
+
+
+
+
+
+
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G7_Replay\MakeReplay\for_testing\MakeReplay.dll
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G7_Replay\MakeReplay\for_testing\MakeReplay_overview.html
+ C:\Projects\epb-matlab\Intellirupters\toGPA_G7_Replay\MakeReplay\for_testing\MakeReplayNative.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/Intellirupters/toGPA_G7_Replay/SnC_G7_Replay.prj b/Intellirupters/toGPA_G7_Replay/SnC_G7_Replay.prj
new file mode 100644
index 0000000..ca102a2
--- /dev/null
+++ b/Intellirupters/toGPA_G7_Replay/SnC_G7_Replay.prj
@@ -0,0 +1,139 @@
+
+
+ SnC_G7_Replay
+
+
+ 1.0
+
+
+
+
+
+
+
+ \SnC_G7_Replay\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\SnC_G7_Replay\for_testing
+ ${PROJECT_ROOT}\SnC_G7_Replay\for_redistribution_files_only
+ ${PROJECT_ROOT}\SnC_G7_Replay\for_redistribution
+ ${PROJECT_ROOT}\SnC_G7_Replay
+ false
+
+ subtarget.net.component
+
+ SnC_G7_Replay
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ SnC_G7_Replay
+ Analytic
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G7_Replay
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\AustinG7.m
+
+
+
+
+ ${PROJECT_ROOT}\AustinG7.m
+
+
+
+
+
+
+
+
+
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G7_Replay\SnC_G7_Replay\for_testing\SnC_G7_Replay.dll
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G7_Replay\SnC_G7_Replay\for_testing\SnC_G7_Replay_overview.html
+ C:\Projects\epb-matlab\Intellirupters\toGPA_SnC_G7_Replay\SnC_G7_Replay\for_testing\SnC_G7_ReplayNative.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/toGPA_G7_Replay/classification.txt b/Intellirupters/toGPA_G7_Replay/classification.txt
similarity index 100%
rename from toGPA_G7_Replay/classification.txt
rename to Intellirupters/toGPA_G7_Replay/classification.txt
diff --git a/toGPA_G7_Replay/colorIndex.txt b/Intellirupters/toGPA_G7_Replay/colorIndex.txt
similarity index 100%
rename from toGPA_G7_Replay/colorIndex.txt
rename to Intellirupters/toGPA_G7_Replay/colorIndex.txt
diff --git a/Intellirupters/toGPA_G7_Replay/groupVoltCurr.m b/Intellirupters/toGPA_G7_Replay/groupVoltCurr.m
new file mode 100644
index 0000000..b326880
--- /dev/null
+++ b/Intellirupters/toGPA_G7_Replay/groupVoltCurr.m
@@ -0,0 +1,70 @@
+%% groupVoltCurr.m - This function takes in a structure containing the
+% analog channels from a COMTRADE file.
+% Inputs:
+% o analogChannels: Structure containing the analog channels
+%
+% Outputs:
+% o Imatrix: Matrix of current vectors, ordered in 1, 2, 3 or A, B, C
+% fashion
+% o Vmatrix: Matrix of voltage vectors, ordered in 1, 2, 3 or A, B, C
+% fashion
+% o numSensors: The total number of sensors collected (not included
+% Di/Dt channels)
+% o sensorInfo: Information about the sensors. This argument tells if
+% the sensors use A,B,C, or 1,2,3 orientation.
+% *sensorInfo.type = 'ABC', or '123'.
+%
+% Written by: Aaron Wilson, 6/22/2018
+
+function [Imatrix,Vmatrix,numSensors,sensorInfo] = groupVoltCurr(analogChannels)
+
+ N = numel(fieldnames(analogChannels));
+
+ % Temporary matrices to store stuff in:
+ Itemp = []; Vtemp = [];
+ Inames = []; Vnames = [];
+
+ % Names of sensors in analog channel struct
+ sensorNames = fieldnames(analogChannels);
+
+ for k = 1:numel(fieldnames(analogChannels))
+
+ channelName = sensorNames{k};
+
+ % Ignoring Di/Dt channels
+ if strcmp(channelName(1),'D')
+ continue
+ % Ignoring VDC channels
+ elseif length(channelName)>2 && strcmp(channelName(1:3),'VDC')
+ continue
+ elseif length(channelName)>3 && strcmp(channelName(1:4),'VBAT')
+ continue
+ elseif strcmp(channelName(1:2),'VS')
+ continue
+
+ elseif strcmp(channelName(1),'I')
+ nextCurUp = getfield(analogChannels,channelName);
+ Itemp = cat(1,Itemp, nextCurUp');
+ Inames = cat(1,Inames,channelName);
+
+ elseif strcmp(channelName(1),'V')
+ nextVolUp = getfield(analogChannels,channelName);
+ Vtemp = cat(1,Vtemp,nextVolUp');
+ Vnames = cat(1,Vnames,channelName);
+
+ end
+
+ end
+
+ if (strcmp(Inames(1,2),'1') || strcmp(Inames(1,2),'2') || strcmp(Inames(1,2),'3'))
+ sensorInfo.type = '123';
+ elseif (strcmp(Inames(1,2),'A') || strcmp(Inames(1,2),'B') || strcmp(Inames(1,2),'C'))
+ sensorInfo.type = 'ABC';
+ end
+
+ Imatrix = Itemp;
+ Vmatrix = Vtemp;
+ numSensors = size(Inames,1) + size(Vnames,1);
+
+end
+
diff --git a/toGPA_G7_Replay/readCFG_COMTRADE.m b/Intellirupters/toGPA_G7_Replay/readCFG_COMTRADE.m
similarity index 100%
rename from toGPA_G7_Replay/readCFG_COMTRADE.m
rename to Intellirupters/toGPA_G7_Replay/readCFG_COMTRADE.m
diff --git a/toGPA_G7_Replay/readDAT_COMTRADE.m b/Intellirupters/toGPA_G7_Replay/readDAT_COMTRADE.m
similarity index 100%
rename from toGPA_G7_Replay/readDAT_COMTRADE.m
rename to Intellirupters/toGPA_G7_Replay/readDAT_COMTRADE.m
diff --git a/toGPA_G7_Replay/AustinG7.m b/SEL/toGPA_G7_Replay/AustinG7.m
similarity index 95%
rename from toGPA_G7_Replay/AustinG7.m
rename to SEL/toGPA_G7_Replay/AustinG7.m
index c06c22d..d0fe521 100644
--- a/toGPA_G7_Replay/AustinG7.m
+++ b/SEL/toGPA_G7_Replay/AustinG7.m
@@ -1,53 +1,51 @@
-
-clc
-clear all
-global currentFolder
-currentFolder = pwd;
-folderPath = horzcat(currentFolder,'\Input');
-D = genpath(folderPath);
-fileFolders = split(D,';');
-max = size(fileFolders);
-max = max(1,1);
-i = 0;
-for i = 2:max
- fileFolders{i,1};
- currentfile = string(fileFolders{i,1});
- S = strcat(currentfile,'\','*.DAT');
-
- files = dir(S);
- for file = files'
- the_size = file.bytes;
- if the_size > 10000
- path1 = strcat(currentFolder,'\','classification.txt');
- GBB_local = importGBBlistFile150SubFunction(path1);
- dat_file = strcat(currentfile,'\',file.name);
- dat_file = char(dat_file);
- cfg_file = strcat(dat_file(1:end-3),'CFG');
- waveFormCfg = readCFG_COMTRADE(cfg_file);
- waveFormDat = readDAT_COMTRADE(dat_file,waveFormCfg);
- [Imat,Vmat,~,~] = groupVoltCurr(waveFormDat.analog);
- p1_g6stateChangeHistoryV2(waveFormCfg,Vmat,Imat,dat_file,i,currentFolder);
- i = i + 1;
- end
-
+function tags = p1_g6stateChangeHistoryV2Analytic(Voltage, Current, Fs, Setting)
+ tags = [];
+ if ~Setting.ExecuteAnalytic
+ return
end
+ Vmat = [];
+ Imat = [];
+ Vmat = cat(1, Vmat, Voltage(:,7)'); % VA
+ Vmat = cat(1, Vmat, Voltage(:,8)'); % VB
+ Vmat = cat(1, Vmat, Voltage(:,9)'); % VC
+ Imat = cat(1, Imat, Current(:,5)'); % IA
+ Imat = cat(1, Imat, Current(:,6)'); % IB
+ Imat = cat(1, Imat, Current(:,7)'); % IC
+
+ classificationsPath = convertStringsToChars(Setting.ClassificationsPath);
+ GBB_local = importGBBlistFile150SubFunction(classificationsPath);
+ GBB_local = table2struct(GBB_local);
+
+ cfg = struct;
+ cfg.station_name = convertStringsToChars(Setting.Station);
+ cfg.recording_device = convertStringsToChars(Setting.Device);
+ cfg.lf = Setting.SystemFrequency;
+ cfg.samp = Fs;
+ cfg.endsamp = Setting.SampleCount;
+ cfg.startdate = convertStringsToChars(Setting.EventDate);
+ cfg.starttime = convertStringsToChars(Setting.EventTime);
+ cfg.eventID = Setting.Event_ID;
+ cfg.soeID = Setting.SOE_ID;
+ cfg.soeTime = Setting.SOE_Time;
+ cfg.incidentID = Setting.Incident_ID;
+
+ dat_file = convertStringsToChars("\\\\\" + Setting.InputFilename);
+ outputFolder = convertStringsToChars(Setting.OutputFolder);
-
+ global currentFolder
+ currentFolder = outputFolder
+ result = p1_g6stateChangeHistoryV2(cfg, Vmat, Imat, dat_file, 0, outputFolder);
+
+ if isfield(result, 'plotFilePath')
+ tag = struct;
+ tag.Name = 'G7 State Change Plot';
+ tag.Data = struct;
+ tag.Data.PlotFilePath = result.plotFilePath;
+ tags = [tags, tag];
+ end
end
-
-
-% GBB_local = importGBBlistFile150SubFunction('D:\_gbbR06.11\classificationGBB2.xx.txt');
-% dat_file = 'D:\GBB_CT\PCR_inBox\CT-145290\HAL201-HB4408\HAL201-HB4408_WFCAP10.1670370786000.DAT';
-% cfg_file = strcat(dat_file(1:end-3),'CFG');
-% waveFormCfg = readCFG_COMTRADE(cfg_file);
-% waveFormDat = readDAT_COMTRADE(dat_file,waveFormCfg);
-% [Imat,Vmat,~,~] = groupVoltCurr(waveFormDat.analog);
-% p1_g6stateChangeHistoryV2(waveFormCfg,Vmat,Imat,dat_file);
-
-
-
function sb = p1_g6stateChangeHistoryV2(wfCfg,Vmatrix,Imatrix,dat_file,i,currentFolder)
@@ -460,6 +458,7 @@ function sb = p1_g6stateChangeHistoryV2(wfCfg,Vmatrix,Imatrix,dat_file,i,current
warning off MATLAB:print:UIControlsScaled %surpresses resizing warning
set(figG6hist,'PaperUnits','inches','PaperPosition',[0 0 17 11]);
print(figG6hist, plotPathFile,'-dpng');
+ sb.plotFilePath = plotPathFile;
close(figG6hist);
@@ -1527,10 +1526,11 @@ function sb = p1_stateChangeDataLogV2SubFunction(action,inLog,newRecords,Circuit
if strcmp(action,'setCommonValues')
sb = inLog; % must preserve what was passed in
cv = inLog.colValue; % local copy to reduce struct name size
- cv.SOE_ID = -1;
+ cv.EventID = wfCfg.eventID;
+ cv.SOE_ID = wfCfg.soeID;
cv.Circuit = char(device4);
cv.DeviceName = char(device4);
- cv.SOEdateTimeLocal = 'Time the SOE begins';
+ cv.SOEdateTimeLocal = wfCfg.soeTime;
voltagelevel = extract(cv.Circuit,5);
voltagelevel = char(voltagelevel);
voltCheck = char(device4)
@@ -1542,7 +1542,7 @@ function sb = p1_stateChangeDataLogV2SubFunction(action,inLog,newRecords,Circuit
end
- cv.IncidentID = 'IncidentIDgoesHere';
+ cv.IncidentID = wfCfg.incidentID;
sb.colValue = cv; % send back assigned values
return;
end
diff --git a/toGPA_G7_Replay/MakeReplay.m b/SEL/toGPA_G7_Replay/MakeReplay.m
similarity index 100%
rename from toGPA_G7_Replay/MakeReplay.m
rename to SEL/toGPA_G7_Replay/MakeReplay.m
diff --git a/SEL/toGPA_G7_Replay/SEL_G7_Replay.prj b/SEL/toGPA_G7_Replay/SEL_G7_Replay.prj
new file mode 100644
index 0000000..a80644e
--- /dev/null
+++ b/SEL/toGPA_G7_Replay/SEL_G7_Replay.prj
@@ -0,0 +1,139 @@
+
+
+ SEL_G7_Replay
+
+
+ 1.0
+
+
+
+
+
+
+
+ \SEL_G7_Replay\
+ option.installpath.programfiles
+
+
+
+ ${PROJECT_ROOT}\SEL_G7_Replay\for_testing
+ ${PROJECT_ROOT}\SEL_G7_Replay\for_redistribution_files_only
+ ${PROJECT_ROOT}\SEL_G7_Replay\for_redistribution
+ ${PROJECT_ROOT}\SEL_G7_Replay
+ false
+
+ subtarget.net.component
+
+ SEL_G7_Replay
+
+ true
+ false
+ false
+ MyAppInstaller_web
+ MyAppInstaller_mcr
+ MyAppInstaller_app
+ true
+ false
+
+ false
+ false
+
+ false
+ false
+
+
+ SEL_G7_Replay
+ Analytic
+
+ C:\Projects\epb-matlab\SEL\toGPA_SEL_G7_Replay
+
+ option.cpp.all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${PROJECT_ROOT}\AustinG7.m
+
+
+
+
+ ${PROJECT_ROOT}\AustinG7.m
+
+
+
+
+
+
+
+
+
+ C:\Projects\epb-matlab\SEL\toGPA_SEL_G7_Replay\SEL_G7_Replay\for_testing\SEL_G7_Replay.dll
+ C:\Projects\epb-matlab\SEL\toGPA_SEL_G7_Replay\SEL_G7_Replay\for_testing\SEL_G7_Replay_overview.html
+ C:\Projects\epb-matlab\SEL\toGPA_SEL_G7_Replay\SEL_G7_Replay\for_testing\SEL_G7_ReplayNative.dll
+
+
+
+ C:\Program Files\MATLAB\R2021b
+
+
+
+ false
+ false
+ true
+ false
+ false
+ false
+ false
+ false
+ 10.0
+ false
+ true
+ win64
+ true
+
+
+
\ No newline at end of file
diff --git a/SEL/toGPA_G7_Replay/classification.txt b/SEL/toGPA_G7_Replay/classification.txt
new file mode 100644
index 0000000..d03bfa6
--- /dev/null
+++ b/SEL/toGPA_G7_Replay/classification.txt
@@ -0,0 +1,156 @@
+GBBid Active Group Bucket Bin OperatingDevice Outcome Revision TestCount TestResult TestConflict TBD Other
+GBB101 Yes Group1 WaveformPresent FiveCycles --- --- Rev2.21 0 NoTest FALSE none none
+GBB102 Yes Group1 VoltagePresent TwoDirections --- --- Rev1.50 0 NoTest FALSE none none
+GBB103 No Group1 SomeSourceTwoDir 1PH --- --- Rev1.50 0 NoTest FALSE none none
+GBB104 No Group1 SomeSourceTwoDir 2PH --- --- Rev1.50 0 NoTest FALSE none none
+GBB105 Yes Group1 VoltagePresent OneDirection --- --- Rev1.50 0 NoTest FALSE none none
+GBB106 No Group1 SomeSourceAnyDirection 2PH --- --- Rev1.50 0 NoTest FALSE none none
+GBB107 No Group1 SomeSourceAnyDirection 1PH --- --- Rev1.50 0 NoTest FALSE none none
+GBB108 No Group1 Power PeakCycle --- --- Rev1.50 0 NoTest FALSE none none
+GBB109 Yes Group1 Developer Review --- --- Rev1.50 0 NoTest FALSE none none
+GBB110 Yes Group1 NoBucket NoBin --- --- Rev1.51 0 NoTest FALSE none none
+GBB111 Yes Group1 CurrentPresent FiveCycles --- --- Rev2.38 0 NoTest FALSE none none
+GBB201 Yes Group2 Switching LOS sourceSide sourceLost Rev1.50 0 NoTest FALSE none none
+GBB202 Yes Group2 Switching sourceReturn sourceSide sourcePresent Rev1.50 0 NoTest FALSE none none
+GBB203 Yes Group2 Switching close me energize Rev1.50 0 NoTest FALSE none none
+GBB204 Yes Group2 Switching open me de-energize Rev1.50 0 NoTest FALSE none none
+GBB205 Yes Group2 Switching closeAddLoad downstream loadIncrease Rev1.50 0 NoTest FALSE none none
+GBB206 Yes Group2 Switching openDropLoad downstream loadDecrease Rev1.50 0 NoTest FALSE none none
+GBB207 Yes Group2 Switching openRTNorLT me iPresentToInot Rev1.50 0 NoTest FALSE none none
+GBB208 Yes Group2 Switching closeRTNorLT me iNotToIpresent Rev1.50 0 NoTest FALSE none none
+GBB209 Yes Group2 Developer Review --- --- Rev1.50 0 NoTest FALSE none none
+GBB210 Yes Group2 Protection InferredSourceFault sourceSide LOS Rev1.51 0 NoTest FALSE none none
+GBB211 Yes Group2 Protection InferredMiscordination sourceSide faultClearByLOS Rev1.51 0 NoTest FALSE none none
+GBB212 Yes Group2 Protection Trip me outage Rev1.51 0 NoTest FALSE none none
+GBB213 Yes Group2 Protection InferredFaultTrip downstream PQandFaultClear Rev1.51 0 NoTest FALSE none none
+GBB214 Yes Group2 Protection InferredTrip parallel sagClear Rev1.51 0 NoTest FALSE none none
+GBB215 Yes Group2 ProtectionTripReclose conventionalCase1 upstream sourceReturn Rev1.51 0 NoTest FALSE none none
+GBB216 Yes Group2 ProtectionTripReclose conventionalCase2 me restorePower Rev1.51 0 NoTest FALSE none none
+GBB217 Yes Group2 ProtectionTripReclose pulseCloseCase1 upstream sourceReturn Rev1.51 0 NoTest FALSE none none
+GBB218 Yes Group2 ProtectionTripReclose pulseCloseCase2 me restorePower Rev1.51 0 NoTest FALSE none none
+GBB219 Yes Group2 ProtectionTripReclose pulseCloseCase3 downstream loadIncrease Rev1.51 0 NoTest FALSE none none
+GBB220 Yes Group2 ProtectionTripReclose hardCloseCase1 upstream sourceReturn Rev1.51 0 NoTest FALSE none none
+GBB221 Yes Group2 ProtectionTripReclose hardCloseCase2 me restorePower Rev1.51 0 NoTest FALSE none none
+GBB222 Yes Group2 ProtectionTripReclose hardCloseCase3 downstream loadIncrease Rev1.51 0 NoTest FALSE none none
+GBB223 Yes Group2 NoBucket NoBin none eyesOnData Rev1.51 0 NoTest FALSE none none
+GBB224 Yes Group2 Indeterminate close any eyesOnData Rev1.51 0 NoTest FALSE none none
+GBB225 Yes Group2 Indeterminate open any eyesOnData Rev1.51 0 NoTest FALSE none none
+GBB230 Yes Group2 Pulse1 Undefined --- --- Rev2.32 0 NoTest FALSE none none
+GBB231 Yes Group2 Pulse1 Close me energizePhase1 Rev2.32 0 NoTest FALSE none none
+GBB232 Yes Group2 Pulse1 Fault me abortClose Rev2.32 0 NoTest FALSE none none
+GBB233 Yes Group2 Inrush1 Fault me abortClose Rev2.32 0 NoTest FALSE none none
+GBB234 Yes Group2 Inrush1 CloseFaultReturn me abortClose Rev2.32 0 NoTest FALSE none none
+GBB235 Yes Group2 NoPulse1 Waveform --- --- Rev2.32 0 NoTest FALSE none none
+GBB236 Yes Group2 Pulse1 NoBin --- --- Rev2.32 0 NoTest FALSE none none
+GBB237 Yes Group2 Pulse1 EndOfFile me indeterminate Rev2.32 0 NoTest FALSE none none
+GBB238 Yes Group2 Inrush1 Close me energizePhase1 Rev2.32 0 NoTest FALSE none none
+GBB240 Yes Group2 Pulse2 Undefined --- --- Rev2.32 0 NoTest FALSE none none
+GBB241 Yes Group2 Pulse2 Close me energizePhase2 Rev2.32 0 NoTest FALSE none none
+GBB242 Yes Group2 Pulse2 Fault me restorePower Rev2.32 0 NoTest FALSE none none
+GBB243 Yes Group2 Inrush2 Fault me restorePower Rev2.32 0 NoTest FALSE none none
+GBB244 Yes Group2 Inrush2 CloseFaultReturn me restorePower Rev2.32 0 NoTest FALSE none none
+GBB245 Yes Group2 NoPulse2 Waveform --- --- Rev2.32 0 NoTest FALSE none none
+GBB246 Yes Group2 Pulse2 NoBin --- --- Rev2.32 0 NoTest FALSE none none
+GBB247 Yes Group2 Pulse2 EndOfFile me indeterminate Rev2.32 0 NoTest FALSE none none
+GBB248 Yes Group2 Inrush2 Close me energizePhase2 Rev2.32 0 NoTest FALSE none none
+GBB250 Yes Group2 Pulse3 Undefined --- --- Rev2.32 0 NoTest FALSE none none
+GBB251 Yes Group2 Pulse3 Close me energizePhase2 Rev2.32 0 NoTest FALSE none none
+GBB252 Yes Group2 Pulse3 Fault me restorePower Rev2.32 0 NoTest FALSE none none
+GBB253 Yes Group2 Inrush3 Fault me restorePower Rev2.32 0 NoTest FALSE none none
+GBB254 Yes Group2 Inrush3 CloseFaultReturn me restorePower Rev2.32 0 NoTest FALSE none none
+GBB255 Yes Group2 NoPulse3 Waveform --- --- Rev2.32 0 NoTest FALSE none none
+GBB256 Yes Group2 Pulse3 NoBin --- --- Rev2.32 0 NoTest FALSE none none
+GBB257 Yes Group2 Pulse3 EndOfFile me indeterminate Rev2.32 0 NoTest FALSE none none
+GBB258 Yes Group2 Inrush3 Close me energizePhase2 Rev2.32 0 NoTest FALSE none none
+GBB301 Yes Group3 PowerQuality persist --- --- Rev1.50 0 NoTest FALSE none none
+GBB302 Yes Group3 PowerQuality case1SAG upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB303 Yes Group3 PowerQuality case2SAG me trip Rev1.50 0 NoTest FALSE none none
+GBB304 Yes Group3 PowerQuality case3SAG parallel clear Rev1.50 0 NoTest FALSE none none
+GBB305 Yes Group3 PowerQuality case1Swell upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB306 Yes Group3 PowerQuality case2Swell me trip Rev1.50 0 NoTest FALSE none none
+GBB307 Yes Group3 PowerQuality case3Swell parallel clear Rev1.50 0 NoTest FALSE none none
+GBB308 Yes Group3 Fault persist --- --- Rev1.50 0 NoTest FALSE none none
+GBB309 Yes Group3 Fault LGcase1 upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB310 Yes Group3 Fault LLcase1 upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB311 Yes Group3 Fault LLLcase1 upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB312 Yes Group3 Fault LLGcase1 upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB313 Yes Group3 Fault LLLGcase1 upstream LOS Rev1.50 0 NoTest FALSE none none
+GBB314 Yes Group3 Fault LGcase2 me trip Rev1.50 0 NoTest FALSE none none
+GBB315 Yes Group3 Fault LLcase2 me trip Rev1.50 0 NoTest FALSE none none
+GBB316 Yes Group3 Fault LLLcase2 me trip Rev1.50 0 NoTest FALSE none none
+GBB317 Yes Group3 Fault LLGcase2 me trip Rev1.50 0 NoTest FALSE none none
+GBB318 Yes Group3 Fault LLLGcase2 me trip Rev1.50 0 NoTest FALSE none none
+GBB319 Yes Group3 Fault LGcase3 downstream clear Rev1.50 0 NoTest FALSE none none
+GBB320 Yes Group3 Fault LLcase3 downstream clear Rev1.50 0 NoTest FALSE none none
+GBB321 Yes Group3 Fault LLLcase3 downstream clear Rev1.50 0 NoTest FALSE none none
+GBB322 Yes Group3 Fault LLGcase3 downstream clear Rev1.50 0 NoTest FALSE none none
+GBB323 Yes Group3 Fault LLLGcase2 downstream clear Rev1.50 0 NoTest FALSE none none
+GBB324 Yes Group3 Developer Review --- eyesOnData Rev1.50 0 NoTest FALSE none none
+GBB325 Yes Group3 Fault LGfuse me trip Rev1.51 0 NoTest FALSE none none
+GBB326 Yes Group3 Fault LGfuse downstream clear Rev1.51 0 NoTest FALSE none none
+GBB327 Yes Group3 NoFault NoBin none cleanWaveform Rev2.35 0 NoTest FALSE none none
+GBB328 Yes Group3 PQandFault Summary any --- Rev1.51 0 NoTest FALSE none none
+GBB329 Yes Group3 Fault Short --- --- Rev2.35 0 NoTest FALSE none none
+GBB330 Yes Group3 Fault evolving --- --- Rev2.22 0 NoTest FALSE none none
+GBB331 Yes Group3 Fault multiple --- --- Rev2.22 0 NoTest FALSE none none
+GBB332 Yes Group3 NotPowerQuality NoBin --- --- Rev2.35 0 NoTest FALSE none none
+GBB333 Yes Group3 PowerQuality case4SAG downstream clear Rev2.36 0 NoTest FALSE none none
+GBB334 Yes Group3 PowerQuality case4Swell downstream clear Rev2.36 0 NoTest FALSE none none
+GBB335 Yes Group3 PowerQuality case5SAG indeterminate --- Rev2.36 0 NoTest FALSE none none
+GBB336 Yes Group3 PowerQuality case5Swell indeterminate --- Rev2.36 0 NoTest FALSE none none
+GBB337 Yes Group3 PowerQuality ExcessSwell --- --- Rev2.37 0 NoTest FALSE none none
+GBB401 Yes Group4 Reserved TBD --- --- Rev1.50 0 NoTest FALSE none none
+GBB402 Yes Group4 Replay PQpref --- --- Rev1.50 0 NoTest FALSE none none
+GBB403 Yes Group4 Replay PQalt --- --- Rev1.50 0 NoTest FALSE none none
+GBB404 Yes Group4 Replay Ichange --- --- Rev1.50 0 NoTest FALSE none none
+GBB405 Yes Group4 Replay StateEst --- --- Rev1.50 0 NoTest FALSE none none
+GBB406 Yes Group4 Developer Details --- --- Rev1.50 0 NoTest FALSE none none
+GBB407 Yes Group4 Developer ChangePoints --- --- Rev1.50 0 NoTest FALSE none none
+GBB408 Yes Group4 NoBucket NoBin --- --- Rev1.51 0 NoTest FALSE none none
+GBB501 Yes Group5 CapRinging Energize any any Rev1.50 0 NoTest FALSE none none
+GBB502 Yes Group5 CapRinging FaultResponse any any Rev1.50 0 NoTest FALSE none none
+GBB503 Yes Group5 CapRinging PQevent any any Rev1.50 0 NoTest FALSE none none
+GBB504 Yes Group5 XfmrMagnetize Energize any any Rev1.50 0 NoTest FALSE none none
+GBB505 Yes Group5 XfmrMagnetize FaultResponse any any Rev1.50 0 NoTest FALSE none none
+GBB506 Yes Group5 XfmrMagnetize PQevent any any Rev1.50 0 NoTest FALSE none none
+GBB507 Yes Group5 Harmonics current any any Rev1.50 0 NoTest FALSE none none
+GBB508 Yes Group5 Harmonics voltage any any Rev1.50 0 NoTest FALSE none none
+GBB509 Yes Group5 VoltageNotch PositiveSlope any any Rev1.50 0 NoTest FALSE none none
+GBB510 Yes Group5 VoltageNotch NegativeSlope any any Rev1.50 0 NoTest FALSE none none
+GBB511 Yes Group5 Arcing any any any Rev1.50 0 NoTest FALSE none none
+GBB512 Yes Group5 Arcing WireDown any any Rev1.50 0 NoTest FALSE none none
+GBB513 Yes Group5 Arcing UGcable any any Rev1.50 0 NoTest FALSE none none
+GBB514 Yes Group5 Ferroresonance detected any any Rev1.50 0 NoTest FALSE none none
+GBB515 Yes Group5 DCoffset positive any any Rev1.50 0 NoTest FALSE none none
+GBB516 Yes Group5 DCoffset negative any any Rev1.50 0 NoTest FALSE none none
+GBB517 Yes Group5 DCoffset both any any Rev1.50 0 NoTest FALSE none none
+GBB518 Yes Group5 VoltageNotch any any any Rev1.50 0 NoTest FALSE none none
+GBB519 Yes Group5 VoltageNotch both any any Rev1.50 0 NoTest FALSE none none
+GBB520 Yes Group5 Incipient TBD any any Rev1.50 0 NoTest FALSE none none
+GBB521 Yes Group5 NoBucket NoBin --- --- Rev1.51 0 NoTest FALSE none none
+GBB522 Yes Group5 Developer Review any any Rev1.51 0 NoTest FALSE none none
+GBB601 Yes Group6 MinMaxAvg General --- --- Rev2.15 0 NoTest FALSE none none
+GBB602 Yes Group6 MinMaxAvg Voltage --- --- Rev1.50 0 NoTest FALSE none none
+GBB603 Yes Group6 MinMaxAvg Current --- --- Rev1.50 0 NoTest FALSE none none
+GBB604 Yes Group6 MinMaxAvg PowerVA --- --- Rev1.50 0 NoTest FALSE none none
+GBB605 Yes Group6 MinMaxAvg Impedance --- --- Rev1.50 0 NoTest FALSE none none
+GBB606 Yes Group6 MinMaxAvg EnergyFirstHalf --- --- Rev1.50 0 NoTest FALSE none none
+GBB607 Yes Group6 MinMaxAvg EnergyLastHalf --- --- Rev1.50 0 NoTest FALSE none none
+GBB608 Yes Group6 DisturbanceCheck Persists --- --- Rev1.50 0 NoTest FALSE none none
+GBB609 Yes Group6 DisturbanceCheck None --- --- Rev1.50 0 NoTest FALSE none none
+GBB610 Yes Group6 DisturbanceCheck OneInceptAndClear --- --- Rev1.50 0 NoTest FALSE none none
+GBB611 Yes Group6 DisturbanceCheck InceptEqualClear(>1) --- --- Rev1.50 0 NoTest FALSE none none
+GBB612 Yes Group6 DisturbanceCheck InceptNEclear(>1) --- --- Rev1.50 0 NoTest FALSE none none
+GBB613 Yes Group6 General CurrentImbalance --- --- Rev2.38 0 NoTest FALSE none none
+GBB614 Yes Group6 General ClassificationReport --- --- Rev1.50 0 NoTest FALSE none none
+GBB615 Yes Group6 General VectorAnalysis --- --- Rev2.41 0 NoTest FALSE none none
+GBB620 Yes Group6 General MajorChanges --- --- Rev03.09 0 NoTest FALSE none none
+GBB621 Yes Group6 StateChanges History --- --- Rev03.11 0 NoTest FALSE none none
+GBB700 Yes Group7 IEEE1668RideThrough NoSag --- --- Rev2.35 0 NoTest FALSE none none
+GBB701 Yes Group7 IEEE1668RideThrough SagLG Upstream Clear Rev2.15 0 NoTest FALSE none none
+GBB702 Yes Group7 IEEE1668RideThrough SagLL Upstream Clear Rev2.15 0 NoTest FALSE none none
+GBB703 Yes Group7 IEEE1668RideThrough SagLLL Upstream Clear Rev2.15 0 NoTest FALSE none none
+GBB704 Yes Group7 IEEE1668RideThrough LOS1PH Upstream Clear Rev2.35 0 NoTest FALSE none none
+GBB705 Yes Group7 IEEE1668RideThrough LOS2PH Upstream Clear Rev2.35 0 NoTest FALSE none none
+GBB706 Yes Group7 IEEE1668RideThrough NoBin --- --- Rev2.35 0 NoTest FALSE none none
+GBB999 Yes Group9 TestRecord Ignore --- --- Rev1.51 0 NoTest FALSE none none
diff --git a/SEL/toGPA_G7_Replay/colorIndex.txt b/SEL/toGPA_G7_Replay/colorIndex.txt
new file mode 100644
index 0000000..d2e6b8e
--- /dev/null
+++ b/SEL/toGPA_G7_Replay/colorIndex.txt
@@ -0,0 +1,14 @@
+0 grayNoFirstWF 150 150 150
+1 redCurrent 255 0 0
+2 blueFault800 0 0 255
+3 ltBluePickUp 110 150 250
+4 greenTrip 0 102 0
+5 greenOpen 0 255 0
+6 redSource 200 0 0
+7 tanPQ 255 170 100
+8 pinkFltPQ 250 5 230
+9 blackLOS 0 0 0
+10 orgSglPH 255 255 0
+11 aquaTBD 5 250 250
+12 dkGrayTBD 250 100 0
+100 yada 1 1 1
\ No newline at end of file
diff --git a/toGPA_G7_Replay/groupVoltCurr.m b/SEL/toGPA_G7_Replay/groupVoltCurr.m
similarity index 100%
rename from toGPA_G7_Replay/groupVoltCurr.m
rename to SEL/toGPA_G7_Replay/groupVoltCurr.m
diff --git a/SEL/toGPA_G7_Replay/readCFG_COMTRADE.m b/SEL/toGPA_G7_Replay/readCFG_COMTRADE.m
new file mode 100644
index 0000000..960665d
--- /dev/null
+++ b/SEL/toGPA_G7_Replay/readCFG_COMTRADE.m
@@ -0,0 +1,135 @@
+function data = readCFG_COMTRADE(filename)
+
+fid = fopen(filename); % open the configuration file
+
+qq = fgetl(fid); % read line 1
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.station_name = ww{:}{1};
+data.recording_device = ww{:}{2};
+
+if numel(ww{:})==3
+ data.revision_year = ww{:}{3};
+else
+ data.revision_year = '';
+end
+
+qq = fgetl(fid); % read line 2
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.total_channels = str2double(ww{:}{1});
+data.total_analog = str2double(ww{:}{2}(1:end-1));
+data.total_digital = str2double(ww{:}{3}(1:end-1));
+
+% channel information
+
+for la = 1:data.total_analog % loop through each analog channel
+
+ qq = fgetl(fid); % read line
+ ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+ data.analog.An(la,1) = ww{:}(1);
+
+ eea = ww{:}(2);
+ eeb = strrep(eea,'(','_'); % replace brackets with underscore
+ eec = strrep(eeb,')','_'); % replace brackets with underscore
+ eed = strrep(eec,'/','_'); % replace forward slashes with underscore
+
+ data.analog.ch_id(la,1) = eed;
+
+ data.analog.ph(la,1) = ww{:}(3);
+ data.analog.ccbm(la,1) = ww{:}(4);
+ data.analog.uu(la,1) = ww{:}(5);
+ data.analog.a(la,1) = str2double(ww{:}(6));
+ data.analog.b(la,1) = str2double(ww{:}(7));
+ data.analog.skew(la,1) = str2double(ww{:}(8));
+ data.analog.min(la,1) = str2double(ww{:}(9));
+ data.analog.max(la,1) = str2double(ww{:}(10));
+ data.analog.primary(la,1) = str2double(ww{:}(11));
+ data.analog.secondary(la,1) = str2double(ww{:}(12));
+ data.analog.PS(la,1) = ww{:}(13);
+
+end
+
+
+for ld = 1:data.total_digital % loop througfh digital channels
+
+ qq = fgetl(fid); % read line
+ ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+ data.digital.Dn(ld,1) = ww{:}(1);
+
+ eea = ww{:}(2);
+
+ eeb = strrep(eea,'*',['TEMP',num2str(ld)]); % replace *
+ eec = strrep(eeb,'/','_');
+
+ data.digital.ch_id(ld,1) = eec;
+ data.digital.ph(ld,1) = ww{:}(3);
+ data.digital.ccbm(ld,1) = ww{:}(4);
+ data.digital.y(ld,1) = str2double(ww{:}(5));
+
+end
+
+% line frequency
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.lf = str2double(ww{:});
+
+% number of rates
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.numrates = str2double(ww{:});
+
+% samp, endsamp
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.samp = str2double(ww{:}{1});
+data.endsamp = str2double(ww{:}{2});
+
+
+% startdate starttime
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.startdate = ww{:}{1};
+data.starttime = ww{:}{2};
+
+% triggerdate triggertime
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.triggerdate = ww{:}{1};
+data.triggertime = ww{:}{2};
+
+% filetype
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.filetype = ww{:}{1};
+
+
+% timemult
+
+qq = fgetl(fid); % read line
+ww = textscan(qq,'%s','delimiter',','); % get individual entries
+
+data.timemult = str2double(ww{:}{1});
+
+
+fclose(fid); % rwh - mitigates too many files open error
+
+end
+
+
+
+
diff --git a/SEL/toGPA_G7_Replay/readDAT_COMTRADE.m b/SEL/toGPA_G7_Replay/readDAT_COMTRADE.m
new file mode 100644
index 0000000..3938873
--- /dev/null
+++ b/SEL/toGPA_G7_Replay/readDAT_COMTRADE.m
@@ -0,0 +1,32 @@
+function data = readDAT_COMTRADE(filename,dataCFG)
+
+fid = fopen(filename); % open the data file
+
+nn = repmat('%n',1,dataCFG.total_channels+2); % column format
+
+ww = textscan(fid,nn,'delimiter',','); % read in the data
+
+
+data.time = ww{2}*1e-6;
+
+for la = 1:dataCFG.total_analog
+
+ data.analog.(dataCFG.analog.ch_id{la}) = dataCFG.analog.a(la)*ww{la+2} + dataCFG.analog.b(la);
+
+end
+
+% Correction for: invalid name field name error
+newCh_id = matlab.lang.makeValidName(dataCFG.digital.ch_id);
+for ld = 1:dataCFG.total_digital
+
+ %data.digital.(dataCFG.digital.ch_id{ld}) = ww{la+ld+2}; %original
+ data.digital.(newCh_id{ld}) = ww{la+ld+2}; %correction
+
+end
+
+fclose(fid); % rwh - mitigates too many files open error
+
+end
+
+
+